<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Chapter 28 Extending MySQL</title>
<link rel="stylesheet" href="mvl.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets + chunker.py v1.9.2" />
<link rel="start" href="index.html" title="{book-title}" />
<link rel="up" href="" title="" />
<link rel="prev" href="connectors-apis.html" title="Chapter 27 Connectors and APIs" />
<link rel="next" href="mysql-enterprise.html" title="Chapter 29 MySQL Enterprise Edition" />
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Chapter 28 Extending MySQL</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="connectors-apis.html">Prev</a> </td>
<th width="60%" align="center"></th>
<td width="20%" align="right"> <a accesskey="n" href="mysql-enterprise.html">Next</a></td>
</tr>
</table>
<hr>
</div>
<div class="chapter">
<div class="titlepage">
<div>
<div>
<h1 class="title"><a name="extending-mysql"></a>Chapter 28 Extending MySQL</h1>

</div>

</div>

</div>
<div class="toc">
<p><b>Table of Contents</b></p><dl class="toc"><dt><span class="section"><a href="extending-mysql.html#mysql-internals">28.1 MySQL Internals</a></span></dt><dd><dl><dt><span class="section"><a href="extending-mysql.html#mysql-threads">28.1.1 MySQL Threads</a></span></dt><dt><span class="section"><a href="extending-mysql.html#mysql-test-suite">28.1.2 The MySQL Test Suite</a></span></dt></dl></dd><dt><span class="section"><a href="extending-mysql.html#plugin-api">28.2 The MySQL Plugin API</a></span></dt><dd><dl><dt><span class="section"><a href="extending-mysql.html#plugin-types">28.2.1 Types of Plugins</a></span></dt><dt><span class="section"><a href="extending-mysql.html#plugin-api-characteristics">28.2.2 Plugin API Characteristics</a></span></dt><dt><span class="section"><a href="extending-mysql.html#plugin-api-components">28.2.3 Plugin API Components</a></span></dt><dt><span class="section"><a href="extending-mysql.html#writing-plugins">28.2.4 Writing Plugins</a></span></dt></dl></dd><dt><span class="section"><a href="extending-mysql.html#component-plugin-services">28.3 MySQL Services for Components and Plugins</a></span></dt><dd><dl><dt><span class="section"><a href="extending-mysql.html#locking-service">28.3.1 The Locking Service</a></span></dt><dt><span class="section"><a href="extending-mysql.html#keyring-service">28.3.2 The Keyring Service</a></span></dt></dl></dd><dt><span class="section"><a href="extending-mysql.html#adding-functions">28.4 Adding New Functions to MySQL</a></span></dt><dd><dl><dt><span class="section"><a href="extending-mysql.html#udf-features">28.4.1 Features of the User-Defined Function Interface</a></span></dt><dt><span class="section"><a href="extending-mysql.html#adding-udf">28.4.2 Adding a New User-Defined Function</a></span></dt><dt><span class="section"><a href="extending-mysql.html#adding-native-function">28.4.3 Adding a New Native Function</a></span></dt></dl></dd><dt><span class="section"><a href="extending-mysql.html#porting">28.5 Debugging and Porting MySQL</a></span></dt><dd><dl><dt><span class="section"><a href="extending-mysql.html#debugging-server">28.5.1 Debugging a MySQL Server</a></span></dt><dt><span class="section"><a href="extending-mysql.html#debugging-client">28.5.2 Debugging a MySQL Client</a></span></dt><dt><span class="section"><a href="extending-mysql.html#dbug-package">28.5.3 The DBUG Package</a></span></dt></dl></dd></dl>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="mysql-internals"></a>28.1 MySQL Internals</h2>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="extending-mysql.html#mysql-threads">28.1.1 MySQL Threads</a></span></dt><dt><span class="section"><a href="extending-mysql.html#mysql-test-suite">28.1.2 The MySQL Test Suite</a></span></dt></dl>
</div>
<a class="indexterm" name="idm139899456671296"></a><a class="indexterm" name="idm139899456670224"></a><p>
      This chapter describes a lot of things that you need to know when
      working on the MySQL code. To track or contribute to MySQL
      development, follow the instructions in
      <a class="xref" href="installing.html#installing-development-tree" title="2.9.3 Installing MySQL Using a Development Source Tree">Section 2.9.3, “Installing MySQL Using a Development Source Tree”</a>. If you are
      interested in MySQL internals, you should also subscribe to our
      <code class="literal">internals</code> mailing list. This list has
      relatively low traffic. For details on how to subscribe, please
      see <a class="xref" href="introduction.html#mailing-lists" title="1.6.2 MySQL Mailing Lists">Section 1.6.2, “MySQL Mailing Lists”</a>. Many MySQL developers at
      Oracle Corporation are on the <code class="literal">internals</code> list
      and we help other people who are working on the MySQL code. Feel
      free to use this list both to ask questions about the code and to
      send patches that you would like to contribute to the MySQL
      project!
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
        The MySQL source code contains internal documentation written
        using Doxygen. This documentation is useful for understanding
        how MySQL works from a developer perspective. The generated
        Doxygen content is available at
        <a class="ulink" href="http://dev.mysql.com/doc/dev/mysql-server/latest/" target="_top">http://dev.mysql.com/doc/dev/mysql-server/latest/</a>. It is also
        possible to generate this content locally from a MySQL source
        distribution using the instructions at
        <a class="xref" href="installing.html#source-installation-doxygen" title="2.9.7 Generating MySQL Doxygen Documentation Content">Section 2.9.7, “Generating MySQL Doxygen Documentation Content”</a>.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="mysql-threads"></a>28.1.1 MySQL Threads</h3>

</div>

</div>

</div>
<p>
        The MySQL server creates the following threads:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            Connection manager threads handle client connection requests
            on the network interfaces that the server listens to. On all
            platforms, one manager thread handles TCP/IP connection
            requests. On Unix, this manager thread also handles Unix
            socket file connection requests. On Windows, a manager
            thread handles shared-memory connection requests, and
            another handles named-pipe connection requests. The server
            does not create threads to handle interfaces that it does
            not listen to. For example, a Windows server that does not
            have support for named-pipe connections enabled does not
            create a thread to handle them.
          </p></li><li class="listitem"><p>
            Connection manager threads associate each client connection
            with a thread dedicated to it that handles authentication
            and request processing for that connection. Manager threads
            create a new thread when necessary but try to avoid doing so
            by consulting the thread cache first to see whether it
            contains a thread that can be used for the connection. When
            a connection ends, its thread is returned to the thread
            cache if the cache is not full.
          </p><p>
            For information about tuning the parameters that control
            thread resources, see <a class="xref" href="optimization.html#connection-threads" title="8.12.4.1 How MySQL Uses Threads for Client Connections">Section 8.12.4.1, “How MySQL Uses Threads for Client Connections”</a>.
          </p></li><li class="listitem"><p>
            On a master replication server, connections from slave
            servers are handled like client connections: There is one
            thread per connected slave.
          </p></li><li class="listitem"><p>
            On a slave replication server, an I/O thread is started to
            connect to the master server and read updates from it. An
            SQL thread is started to apply updates read from the master.
            These two threads run independently and can be started and
            stopped independently.
          </p></li><li class="listitem"><p>
            A signal thread handles all signals. This thread also
            normally handles alarms and calls
            <code class="literal">process_alarm()</code> to force timeouts on
            connections that have been idle too long.
          </p></li><li class="listitem"><p>
            If <code class="literal">InnoDB</code> is used, there will be
            additional read and write threads by default. The number of
            these are controlled by the
            <a class="link" href="innodb-storage-engine.html#sysvar_innodb_read_io_threads"><code class="literal">innodb_read_io_threads</code></a> and
            <a class="link" href="innodb-storage-engine.html#sysvar_innodb_write_io_threads"><code class="literal">innodb_write_io_threads</code></a>
            parameters. See <a class="xref" href="innodb-storage-engine.html#innodb-parameters" title="15.13 InnoDB Startup Options and System Variables">Section 15.13, “InnoDB Startup Options and System Variables”</a>.
          </p></li><li class="listitem"><p>
            If the server is started with the
            <a class="link" href="server-administration.html#sysvar_flush_time"><code class="option">--flush_time=<em class="replaceable"><code>val</code></em></code></a>
            option, a dedicated thread is created to flush all tables
            every <em class="replaceable"><code>val</code></em> seconds.
          </p></li><li class="listitem"><p>
            If the event scheduler is active, there is one thread for
            the scheduler, and a thread for each event currently
            running. See <a class="xref" href="stored-programs-views.html#events-overview" title="23.4.1 Event Scheduler Overview">Section 23.4.1, “Event Scheduler Overview”</a>.
</p></li></ul>
</div>
<p>
        <a class="link" href="programs.html#mysqladmin" title="4.5.2 mysqladmin — Client for Administering a MySQL Server"><span class="command"><strong>mysqladmin processlist</strong></span></a> only shows the
        connection, replication, and event threads.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="mysql-test-suite"></a>28.1.2 The MySQL Test Suite</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm139899456641168"></a><a class="indexterm" name="idm139899456639680"></a><p>
        The test system that is included in Unix source and binary
        distributions makes it possible for users and developers to
        perform regression tests on the MySQL code. These tests can be
        run on Unix.
      </p><p>
        You can also write your own test cases. For information about
        the MySQL Test Framework, including system requirements, see the
        manual available at <a class="ulink" href="http://dev.mysql.com/doc/mysqltest/2.0/en/" target="_top">http://dev.mysql.com/doc/mysqltest/2.0/en/</a>.
      </p><p>
        The current set of test cases does not test everything in MySQL,
        but it should catch most obvious bugs in the SQL processing
        code, operating system or library issues, and is quite thorough
        in testing replication. Our goal is to have the tests cover 100%
        of the code. We welcome contributions to our test suite. You may
        especially want to contribute tests that examine the
        functionality critical to your system because this ensures that
        all future MySQL releases work well with your applications.
      </p><p>
        The test system consists of a test language interpreter
        (<span class="command"><strong>mysqltest</strong></span>), a Perl script to run all tests
        (<span class="command"><strong>mysql-test-run.pl</strong></span>), the actual test cases
        written in a special test language, and their expected results.
        To run the test suite on your system after a build, type
        <span class="command"><strong>make test</strong></span> from the source root directory, or
        change location to the <code class="filename">mysql-test</code> directory
        and type <span class="command"><strong>./mysql-test-run.pl</strong></span>. If you have
        installed a binary distribution, change location to the
        <code class="filename">mysql-test</code> directory under the installation
        root directory (for example,
        <code class="filename">/usr/local/mysql/mysql-test</code>), and run
        <span class="command"><strong>./mysql-test-run.pl</strong></span>. All tests should
        succeed. If any do not, feel free to try to find out why and
        report the problem if it indicates a bug in MySQL. See
        <a class="xref" href="introduction.html#bug-reports" title="1.7 How to Report Bugs or Problems">Section 1.7, “How to Report Bugs or Problems”</a>.
      </p><p>
        If one test fails, you should run
        <span class="command"><strong>mysql-test-run.pl</strong></span> with the
        <code class="option">--force</code> option to check whether any other tests
        fail.
      </p><p>
        If you have a copy of <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> running on the
        machine where you want to run the test suite, you do not have to
        stop it, as long as it is not using ports
        <code class="literal">9306</code> or <code class="literal">9307</code>. If either of
        those ports is taken, you should set the
        <code class="literal">MTR_BUILD_THREAD</code> environment variable to an
        appropriate value, and the test suite will use a different set
        of ports for master, slave, and NDB). For example:
      </p><pre class="programlisting">
shell&gt; export MTR_BUILD_THREAD=31
shell&gt; ./mysql-test-run.pl [<em class="replaceable"><code>options</code></em>] [<em class="replaceable"><code>test_name</code></em>]
</pre><p>
        In the <code class="filename">mysql-test</code> directory, you can run an
        individual test case with <span class="command"><strong>./mysql-test-run.pl
        <em class="replaceable"><code>test_name</code></em></strong></span>.
      </p><p>
        If you have a question about the test suite, or have a test case
        to contribute, send an email message to the MySQL
        <code class="literal">internals</code> mailing list. See
        <a class="xref" href="introduction.html#mailing-lists" title="1.6.2 MySQL Mailing Lists">Section 1.6.2, “MySQL Mailing Lists”</a>.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="plugin-api"></a>28.2 The MySQL Plugin API</h2>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="extending-mysql.html#plugin-types">28.2.1 Types of Plugins</a></span></dt><dt><span class="section"><a href="extending-mysql.html#plugin-api-characteristics">28.2.2 Plugin API Characteristics</a></span></dt><dt><span class="section"><a href="extending-mysql.html#plugin-api-components">28.2.3 Plugin API Components</a></span></dt><dt><span class="section"><a href="extending-mysql.html#writing-plugins">28.2.4 Writing Plugins</a></span></dt></dl>
</div>
<a class="indexterm" name="idm139899456615088"></a><a class="indexterm" name="idm139899456614016"></a><p>
      MySQL supports a plugin API that enables creation of server
      components. Plugins can be loaded at server startup, or loaded and
      unloaded at runtime without restarting the server. The API is
      generic and does not specify what plugins can do. The components
      supported by this interface include, but are not limited to,
      storage engines, full-text parser plugins, and server extensions.
    </p><p>
      For example, full-text parser plugins can be used to replace or
      augment the built-in full-text parser. A plugin can parse text
      into words using rules that differ from those used by the built-in
      parser. This can be useful if you need to parse text with
      characteristics different from those expected by the built-in
      parser.
    </p><p>
      The plugin interface is more general than the older user-defined
      function (UDF) interface.

    </p><p>
      The plugin interface uses the <code class="literal">plugin</code> table in
      the <code class="literal">mysql</code> database to record information about
      plugins that have been installed permanently with the
      <a class="link" href="sql-syntax.html#install-plugin" title="13.7.4.4 INSTALL PLUGIN Syntax"><code class="literal">INSTALL PLUGIN</code></a> statement. This
      table is created as part of the MySQL installation process.
      Plugins can also be installed for a single server invocation with
      the <code class="option">--plugin-load</code> option. Plugins installed this
      way are not recorded in the <code class="literal">plugin</code> table. See
      <a class="xref" href="server-administration.html#server-plugin-loading" title="5.6.1 Installing and Uninstalling Plugins">Section 5.6.1, “Installing and Uninstalling Plugins”</a>.
    </p><p>
      MySQL supports an API for client plugins in addition to that for
      server plugins. This is used, for example, by authentication
      plugins where a server-side plugin and a client-side plugin
      cooperate to enable clients to connect to the server through a
      variety of authentication methods.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
        The MySQL source code contains internal documentation written
        using Doxygen. This documentation is useful for understanding
        how MySQL works from a developer perspective. The generated
        Doxygen content is available at
        <a class="ulink" href="http://dev.mysql.com/doc/dev/mysql-server/latest/" target="_top">http://dev.mysql.com/doc/dev/mysql-server/latest/</a>. It is also
        possible to generate this content locally from a MySQL source
        distribution using the instructions at
        <a class="xref" href="installing.html#source-installation-doxygen" title="2.9.7 Generating MySQL Doxygen Documentation Content">Section 2.9.7, “Generating MySQL Doxygen Documentation Content”</a>.
</p>
</div>
<h3><a name="idm139899456600736"></a>Additional Resources</h3>
<p>
      The book <em class="citetitle">MySQL 5.1 Plugin Development</em> by
      Sergei Golubchik and Andrew Hutchings provides a wealth of detail
      about the plugin API. Despite the fact that the book's title
      refers to MySQL Server 5.1, most of the information in it applies
      to later versions as well.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="plugin-types"></a>28.2.1 Types of Plugins</h3>
</div>
</div>
</div>
<p>
        The plugin API enables creation of plugins that implement
        several capabilities:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <a class="link" href="extending-mysql.html#storage-engine-plugin-type" title="Storage Engine Plugins">Storage
            engines</a>
          </p></li><li class="listitem"><p>
            <a class="link" href="extending-mysql.html#full-text-plugin-type" title="Full-Text Parser Plugins">Full-text
            parsers</a>
          </p></li><li class="listitem"><p>
            <a class="link" href="extending-mysql.html#daemon-plugin-type" title="Daemon Plugins">Daemons</a>
          </p></li><li class="listitem"><p>
            <a class="link" href="extending-mysql.html#information-schema-plugin-type" title="INFORMATION_SCHEMA Plugins"><code class="literal">INFORMATION_SCHEMA</code>
            tables</a>
          </p></li><li class="listitem"><p>
            <a class="link" href="extending-mysql.html#semisynchronous-replication-plugin-type" title="Semisynchronous Replication Plugins">Semisynchronous
            replication</a>
          </p></li><li class="listitem"><p>
            <a class="link" href="extending-mysql.html#audit-plugin-type" title="Audit Plugins">Auditing</a>
          </p></li><li class="listitem"><p>
            <a class="link" href="extending-mysql.html#authentication-plugin-type" title="Authentication Plugins">Authentication</a>
          </p></li><li class="listitem"><p>
            <a class="link" href="extending-mysql.html#password-validation-plugin-type" title="Password-Validation Plugins">Password
            validation and strength checking</a>
          </p></li><li class="listitem"><p>
            <a class="link" href="extending-mysql.html#protocol-trace-plugin-type" title="Protocol Trace Plugins">Protocol
            tracing</a>
          </p></li><li class="listitem"><p>
            <a class="link" href="extending-mysql.html#query-rewrite-plugin-type" title="Query Rewrite Plugins">Query
            rewriting</a>
          </p></li><li class="listitem"><p>
            <a class="link" href="extending-mysql.html#keyring-plugin-type" title="Keyring Plugins">Secure keyring storage
            and retrieval</a>
</p></li></ul>
</div>
<p>
        The following sections provide an overview of these plugin
        types.
</p>
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h4 class="title"><a name="storage-engine-plugin-type"></a>Storage Engine Plugins</h4>
</div>
</div>
</div>
<a class="indexterm" name="idm139899456575872"></a><a class="indexterm" name="idm139899456574800"></a><p>
          The pluggable storage engine architecture used by MySQL Server
          enables storage engines to be written as plugins and loaded
          into and unloaded from a running server. For a description of
          this architecture, see
          <a class="xref" href="storage-engines.html#pluggable-storage-overview" title="16.11 Overview of MySQL Storage Engine Architecture">Section 16.11, “Overview of MySQL Storage Engine Architecture”</a>.
        </p><p>
          For information on how to use the plugin API to write storage
          engines, see
          <a class="ulink" href="http://dev.mysql.com/doc/internals/en/custom-engine.html" target="_top">MySQL
          Internals: Writing a Custom Storage Engine</a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="full-text-plugin-type"></a>Full-Text Parser Plugins</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm139899456569392"></a><a class="indexterm" name="idm139899456568336"></a><p>
          MySQL has a built-in parser that it uses by default for
          full-text operations (parsing text to be indexed, or parsing a
          query string to determine the terms to be used for a search).
          The built-in full-text parser is supported with
          <code class="literal">InnoDB</code> and <code class="literal">MyISAM</code>
          tables.
        </p><p>
          MySQL also has a character-based ngram full-text parser that
          supports Chinese, Japanese, and Korean (CJK), and a word-based
          MeCab parser plugin that supports Japanese, for use with
          <code class="literal">InnoDB</code> and <code class="literal">MyISAM</code>
          tables.
        </p><p>
          For full-text processing, <span class="quote">“<span class="quote">parsing</span>”</span> means
          extracting words (or <span class="quote">“<span class="quote">tokens</span>”</span>, in the case of an
          n-gram character-based parser) from text or a query string
          based on rules that define which character sequences make up a
          word and where word boundaries lie.
        </p><p>
          When parsing for indexing purposes, the parser passes each
          word to the server, which adds it to a full-text index. When
          parsing a query string, the parser passes each word to the
          server, which accumulates the words for use in a search.
        </p><p>
          The parsing properties of the built-in full-text parser are
          described in <a class="xref" href="functions.html#fulltext-search" title="12.9 Full-Text Search Functions">Section 12.9, “Full-Text Search Functions”</a>. These
          properties include rules for determining how to extract words
          from text. The parser is influenced by certain system
          variables that cause words shorter or longer to be excluded,
          and by the stopword list that identifies common words to be
          ignored. For more information, see
          <a class="xref" href="functions.html#fulltext-stopwords" title="12.9.4 Full-Text Stopwords">Section 12.9.4, “Full-Text Stopwords”</a>, and
          <a class="xref" href="functions.html#fulltext-fine-tuning" title="12.9.6 Fine-Tuning MySQL Full-Text Search">Section 12.9.6, “Fine-Tuning MySQL Full-Text Search”</a>.
        </p><p>
          The plugin API enables you to use a full-text parser other
          than the default built-in full-text parser. For example, if
          you are working with Japanese, you may choose to use the MeCab
          full-text parser. The plugin API also enables you to provide a
          full-text parser of your own so that you have control over the
          basic duties of a parser. A parser plugin can operate in
          either of two roles:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              The plugin can replace the built-in parser. In this role,
              the plugin reads the input to be parsed, splits it up into
              words, and passes the words to the server (either for
              indexing or for token accumulation). The ngram and MeCab
              parsers operate as replacements for the built-in full-text
              parser.
            </p><p>
              You may choose to provide your own full-text parser if you
              need to use different rules from those of the built-in
              parser for determining how to split up input into words.
              For example, the built-in parser considers the text
              <span class="quote">“<span class="quote">case-sensitive</span>”</span> to consist of two words
              <span class="quote">“<span class="quote">case</span>”</span> and <span class="quote">“<span class="quote">sensitive,</span>”</span> whereas
              an application might need to treat the text as a single
              word.
            </p></li><li class="listitem"><p>
              The plugin can act in conjunction with the built-in parser
              by serving as a front end for it. In this role, the plugin
              extracts text from the input and passes the text to the
              parser, which splits up the text into words using its
              normal parsing rules. This parsing is affected by the
              <code class="literal">innodb_ft_<em class="replaceable"><code>xxx</code></em></code>
              or <code class="literal">ft_<em class="replaceable"><code>xxx</code></em></code>
              system variables and the stopword list.
            </p><p>
              One reason to use a parser this way is that you need to
              index content such as PDF documents, XML documents, or
              <code class="filename">.doc</code> files. The built-in parser is
              not intended for those types of input but a plugin can
              pull out the text from these input sources and pass it to
              the built-in parser.
</p></li></ul>
</div>
<p>
          It is also possible for a parser plugin to operate in both
          roles. That is, it could extract text from noncleartext input
          (the front end role), and also parse the text into words (thus
          replacing the built-in parser).
        </p><p>
          A full-text plugin is associated with full-text indexes on a
          per-index basis. That is, when you install a parser plugin
          initially, that does not cause it to be used for any full-text
          operations. It simply becomes available. For example, a
          full-text parser plugin becomes available to be named in a
          <code class="literal">WITH PARSER</code> clause when creating individual
          <code class="literal">FULLTEXT</code> indexes. To create such an index
          at table-creation time, do this:
        </p><pre class="programlisting">
CREATE TABLE t
(
  doc CHAR(255),
  FULLTEXT INDEX (doc) WITH PARSER parser_name
) ENGINE=InnoDB;
</pre><p>
          Or you can add the index after the table has been created:
        </p><pre class="programlisting">
ALTER TABLE t ADD FULLTEXT INDEX (doc) WITH PARSER parser_name;
</pre><p>
          The only SQL change for associating the parser with the index
          is the <code class="literal">WITH PARSER</code> clause. Searches are
          specified as before, with no changes needed for queries.
        </p><p>
          When you associate a parser plugin with a
          <code class="literal">FULLTEXT</code> index, the plugin is required for
          using the index. If the parser plugin is dropped, any index
          associated with it becomes unusable. Any attempt to use a
          table for which a plugin is not available results in an error,
          although <a class="link" href="sql-syntax.html#drop-table" title="13.1.29 DROP TABLE Syntax"><code class="literal">DROP TABLE</code></a> is still
          possible.
        </p><p>
          For more information about full-text plugins, see
          <a class="xref" href="extending-mysql.html#writing-full-text-plugins" title="28.2.4.4 Writing Full-Text Parser Plugins">Section 28.2.4.4, “Writing Full-Text Parser Plugins”</a>. MySQL
          8.0 supports full-text plugins with
          <a class="link" href="storage-engines.html#myisam-storage-engine" title="16.2 The MyISAM Storage Engine"><code class="literal">MyISAM</code></a> and
          <a class="link" href="innodb-storage-engine.html" title="Chapter 15 The InnoDB Storage Engine"><code class="literal">InnoDB</code></a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="daemon-plugin-type"></a>Daemon Plugins</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm139899456534128"></a><a class="indexterm" name="idm139899456533056"></a><p>
          A daemon plugin is a simple type of plugin used for code that
          should be run by the server but that does not communicate with
          it. MySQL distributions include an example daemon plugin that
          writes periodic heartbeat messages to a file.
        </p><p>
          For more information about daemon plugins, see
          <a class="xref" href="extending-mysql.html#writing-daemon-plugins" title="28.2.4.5 Writing Daemon Plugins">Section 28.2.4.5, “Writing Daemon Plugins”</a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="information-schema-plugin-type"></a>INFORMATION_SCHEMA Plugins</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm139899456528288"></a><a class="indexterm" name="idm139899456527200"></a><p>
          <code class="literal">INFORMATION_SCHEMA</code> plugins enable the
          creation of tables containing server metadata that are exposed
          to users through the <code class="literal">INFORMATION_SCHEMA</code>
          database. For example, <code class="literal">InnoDB</code> uses
          <code class="literal">INFORMATION_SCHEMA</code> plugins to provide
          tables that contain information about current transactions and
          locks.
        </p><p>
          For more information about
          <code class="literal">INFORMATION_SCHEMA</code> plugins, see
          <a class="xref" href="extending-mysql.html#writing-information-schema-plugins" title="28.2.4.6 Writing INFORMATION_SCHEMA Plugins">Section 28.2.4.6, “Writing INFORMATION_SCHEMA Plugins”</a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="semisynchronous-replication-plugin-type"></a>Semisynchronous Replication Plugins</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm139899456518880"></a><a class="indexterm" name="idm139899456517792"></a><p>
          MySQL replication is asynchronous by default. With
          semisynchronous replication, a commit performed on the master
          side blocks before returning to the session that performed the
          transaction until at least one slave acknowledges that it has
          received and logged the events for the transaction.
          Semisynchronous replication is implemented through
          complementary master and client plugins. See
          <a class="xref" href="replication.html#replication-semisync" title="17.3.10 Semisynchronous Replication">Section 17.3.10, “Semisynchronous Replication”</a>.
        </p><p>
          For more information about semisynchronous replication
          plugins, see
          <a class="xref" href="extending-mysql.html#writing-semisynchronous-replication-plugins" title="28.2.4.7 Writing Semisynchronous Replication Plugins">Section 28.2.4.7, “Writing Semisynchronous Replication Plugins”</a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="audit-plugin-type"></a>Audit Plugins</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm139899456511648"></a><a class="indexterm" name="idm139899456510576"></a><p>
          The MySQL server provides a pluggable audit interface that
          enables information about server operations to be reported to
          interested parties. Audit notification occurs for these
          operations (although the interface is general and the server
          could be modified to report others):
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              Write a message to the general query log (if the log is
              enabled)
            </p></li><li class="listitem"><p>
              Write a message to the error log
            </p></li><li class="listitem"><p>
              Send a query result to a client
</p></li></ul>
</div>
<p>
          Audit plugins may register with the audit interface to receive
          notification about server operations. When an auditable event
          occurs within the server, the server determines whether
          notification is needed. For each registered audit plugin, the
          server checks the event against those event classes in which
          the plugin is interested and passes the event to the plugin if
          there is a match.
        </p><p>
          This interface enables audit plugins to receive notifications
          only about operations in event classes they consider
          significant and to ignore others. The interface provides for
          categorization of operations into event classes and further
          division into event subclasses within each class.
        </p><p>
          When an audit plugin is notified of an auditable event, it
          receives a pointer to the current THD structure and a pointer
          to a structure that contains information about the event. The
          plugin can examine the event and perform whatever auditing
          actions are appropriate. For example, the plugin can see what
          statement produced a result set or was logged, the number of
          rows in a result, who the current user was for an operation,
          or the error code for failed operations.
        </p><p>
          For more information about audit plugins, see
          <a class="xref" href="extending-mysql.html#writing-audit-plugins" title="28.2.4.8 Writing Audit Plugins">Section 28.2.4.8, “Writing Audit Plugins”</a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="authentication-plugin-type"></a>Authentication Plugins</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm139899456500352"></a><a class="indexterm" name="idm139899456499280"></a><p>
          MySQL supports pluggable authentication. Authentication
          plugins exist on both the server and client sides. Plugins on
          the server side implement authentication methods for use by
          clients when they connect to the server. A plugin on the
          client side communicates with a server-side plugin to provide
          the authentication information that it requires. A client-side
          plugin may interact with the user, performing tasks such as
          soliciting a password or other authentication credentials to
          be sent to the server. See
          <a class="xref" href="security.html#pluggable-authentication" title="6.3.10 Pluggable Authentication">Section 6.3.10, “Pluggable Authentication”</a>.
        </p><p>
          Pluggable authentication also enables proxy user capability,
          in which one user takes the identity of another user. A
          server-side authentication plugin can return to the server the
          name of the user whose identity the connecting user should
          have. See <a class="xref" href="security.html#proxy-users" title="6.3.11 Proxy Users">Section 6.3.11, “Proxy Users”</a>.
        </p><p>
          For more information about authentication plugins, see
          <a class="xref" href="extending-mysql.html#writing-authentication-plugins" title="28.2.4.9 Writing Authentication Plugins">Section 28.2.4.9, “Writing Authentication Plugins”</a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="password-validation-plugin-type"></a>Password-Validation Plugins</h4>

</div>

</div>

</div>
<p>
          The MySQL server provides an interface for writing plugins
          that test passwords. Such a plugin implements two
          capabilities:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              Rejection of too-weak passwords in statements that assign
              passwords (such as <a class="link" href="sql-syntax.html#create-user" title="13.7.1.3 CREATE USER Syntax"><code class="literal">CREATE
              USER</code></a> and <a class="link" href="sql-syntax.html#alter-user" title="13.7.1.1 ALTER USER Syntax"><code class="literal">ALTER
              USER</code></a> statements).
            </p></li><li class="listitem"><p>
              Assessing the strength of potential passwords for the
              <a class="link" href="functions.html#function_validate-password-strength"><code class="literal">VALIDATE_PASSWORD_STRENGTH()</code></a>
              SQL function.
</p></li></ul>
</div>
<p>
          For information about writing this type of plugin, see
          <a class="xref" href="extending-mysql.html#writing-password-validation-plugins" title="28.2.4.10 Writing Password-Validation Plugins">Section 28.2.4.10, “Writing Password-Validation Plugins”</a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="protocol-trace-plugin-type"></a>Protocol Trace Plugins</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm139899456482544"></a><a class="indexterm" name="idm139899456481472"></a><p>
          MySQL supports the use of protocol trace plugins: client-side
          plugins that implement tracing of communication between a
          client and the server that takes place using the client/server
          protocol.
        </p><p>
          For more information about protocol trace plugins, see
          <a class="xref" href="extending-mysql.html#writing-protocol-trace-plugins" title="28.2.4.11 Writing Protocol Trace Plugins">Section 28.2.4.11, “Writing Protocol Trace Plugins”</a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="query-rewrite-plugin-type"></a>Query Rewrite Plugins</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm139899456476896"></a><a class="indexterm" name="idm139899456475824"></a><p>
          MySQL Server supports query rewrite plugins that can examine
          and possibly modify statements received by the server before
          the server executes them. A query rewrite plugin takes
          statements either before or after the server has parsed them.
        </p><p>
          A preparse query rewrite plugin has these characteristics:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              The plugin enables rewriting of SQL statements arriving at
              the server before the server processes them.
            </p></li><li class="listitem"><p>
              The plugin receives a statement string and may return a
              different string.
</p></li></ul>
</div>
<p>
          A postparse query rewrite plugin has these characteristics:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              The plugin enables statement rewriting based on parse
              trees.
            </p></li><li class="listitem"><p>
              The server parses each statement and passes its parse tree
              to the plugin, which may traverse the tree. The plugin can
              return the original tree to the server for further
              processing, or construct a different tree and return that
              instead.
            </p></li><li class="listitem"><p>
              The plugin can use the <code class="literal">mysql_parser</code>
              plugin service for these purposes:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                  To activate statement digest calculation and obtain
                  the normalized version of statements independent of
                  whether the Performance Schema produces digests.
                </p></li><li class="listitem"><p>
                  To traverse parse trees.
                </p></li><li class="listitem"><p>
                  To parse statements. This is useful if the plugin
                  constructs a new statement string from the parse tree.
                  The plugin can have the server parse the string to
                  produce a new tree, then return that tree as the
                  representation of the rewritten statement.
</p></li></ul>
</div>
</li></ul>
</div>
<p>
          For more information about plugin services, see
          <a class="xref" href="extending-mysql.html#component-plugin-services" title="28.3 MySQL Services for Components and Plugins">Section 28.3, “MySQL Services for Components and Plugins”</a>.
        </p><p>
          Preparse and postparse query rewrite plugins share these
          characteristics:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              If a query rewrite plugin is installed, the
              <a class="link" href="server-administration.html#option_mysqld_log-raw"><code class="option">--log-raw</code></a> option affects
              statement logging as follows:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                  Without <a class="link" href="server-administration.html#option_mysqld_log-raw"><code class="option">--log-raw</code></a>, the
                  server logs the statement returned by the query
                  rewrite plugin. This may differ from the statement as
                  received.
                </p></li><li class="listitem"><p>
                  With <a class="link" href="server-administration.html#option_mysqld_log-raw"><code class="option">--log-raw</code></a>, the
                  server logs the original statement as received.
</p></li></ul>
</div>
</li><li class="listitem"><p>
              If a plugin rewrites a statement, the server decides
              whether to write it to the binary log (and thus to any
              replication slaves) based on the rewritten statement, not
              the original statement. If a plugin rewrites only
              <a class="link" href="sql-syntax.html#select" title="13.2.10 SELECT Syntax"><code class="literal">SELECT</code></a> statements to
              <a class="link" href="sql-syntax.html#select" title="13.2.10 SELECT Syntax"><code class="literal">SELECT</code></a> statements, there is
              no impact on binary logging because the server does not
              write <a class="link" href="sql-syntax.html#select" title="13.2.10 SELECT Syntax"><code class="literal">SELECT</code></a> statements to
              the binary log.
            </p></li><li class="listitem"><p>
              If a plugin rewrites a statement, the server produces a
              <code class="literal">Note</code> message that the client can view
              using <a class="link" href="sql-syntax.html#show-warnings" title="13.7.6.40 SHOW WARNINGS Syntax"><code class="literal">SHOW WARNINGS</code></a>.
              Messages have this format, where
              <em class="replaceable"><code>stmt_in</code></em> is the original
              statement and <em class="replaceable"><code>stmt_out</code></em> is the
              rewritten statement:
            </p><pre class="programlisting">
Query '<em class="replaceable"><code>stmt_in</code></em>' rewritten to '<em class="replaceable"><code>stmt_out</code></em>' by a query rewrite plugin
</pre></li></ul>
</div>
<p>
          MySQL distributions include a postparse query rewrite plugin
          named <code class="literal">Rewriter</code>. This plugin is rule based.
          You can add rows to its rules table to cause
          <a class="link" href="sql-syntax.html#select" title="13.2.10 SELECT Syntax"><code class="literal">SELECT</code></a> statement rewriting. For
          more information, see
          <a class="xref" href="server-administration.html#rewriter-query-rewrite-plugin" title="5.6.4 The Rewriter Query Rewrite Plugin">Section 5.6.4, “The Rewriter Query Rewrite Plugin”</a>.
        </p><p>
          Query rewrite plugins use the same API as audit plugins. For
          more information about audit plugins, see
          <a class="xref" href="extending-mysql.html#writing-audit-plugins" title="28.2.4.8 Writing Audit Plugins">Section 28.2.4.8, “Writing Audit Plugins”</a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="keyring-plugin-type"></a>Keyring Plugins</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm139899456438864"></a><a class="indexterm" name="idm139899456437792"></a><p>
          MySQL Server supports keyring plugins that enable internal
          server components and plugins to securely store sensitive
          information for later retrieval.
        </p><p>
          All MySQL distributions include a keyring plugin named
          <code class="literal">keyring_file</code>. MySQL Enterprise Edition distributions include
          additional keyring plugins. See <a class="xref" href="security.html#keyring" title="6.5.4 The MySQL Keyring">Section 6.5.4, “The MySQL Keyring”</a>.
        </p><p>
          For more information about keyring plugins, see
          <a class="xref" href="extending-mysql.html#writing-keyring-plugins" title="28.2.4.12 Writing Keyring Plugins">Section 28.2.4.12, “Writing Keyring Plugins”</a>.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="plugin-api-characteristics"></a>28.2.2 Plugin API Characteristics</h3>

</div>

</div>

</div>
<p>
        The server plugin API has these characteristics:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            All plugins have several things in common.
          </p><p>
            Each plugin has a name that it can be referred to in SQL
            statements, as well as other metadata such as an author and
            a description that provide other information. This
            information can be examined in the
            <a class="link" href="information-schema.html#plugins-table" title="24.15 The INFORMATION_SCHEMA PLUGINS Table"><code class="literal">INFORMATION_SCHEMA.PLUGINS</code></a>
            table or using the <a class="link" href="sql-syntax.html#show-plugins" title="13.7.6.25 SHOW PLUGINS Syntax"><code class="literal">SHOW
            PLUGINS</code></a> statement.
          </p></li><li class="listitem"><p>
            The plugin framework is extendable to accommodate different
            kinds of plugins.
          </p><p>
            Although some aspects of the plugin API are common to all
            types of plugins, the API also permits type-specific
            interface elements so that different types of plugins can be
            created. A plugin with one purpose can have an interface
            most appropriate to its own requirements and not the
            requirements of some other plugin type.
          </p><p>
            Interfaces for several types of plugins exist, such as
            storage engines, full-text parser, and
            <code class="literal">INFORMATION_SCHEMA</code> tables. Others can be
            added.
          </p></li><li class="listitem"><p>
            Plugins can expose information to users.
          </p><p>
            A plugin can implement system and status variables that are
            available through the <a class="link" href="sql-syntax.html#show-variables" title="13.7.6.39 SHOW VARIABLES Syntax"><code class="literal">SHOW
            VARIABLES</code></a> and <a class="link" href="sql-syntax.html#show-status" title="13.7.6.35 SHOW STATUS Syntax"><code class="literal">SHOW
            STATUS</code></a> statements.
          </p></li><li class="listitem"><p>
            The plugin API includes versioning information.
          </p><p>
            The version information included in the plugin API enables a
            plugin library and each plugin that it contains to be
            self-identifying with respect to the API version that was
            used to build the library. If the API changes over time, the
            version numbers will change, but a server can examine a
            given plugin library's version information to determine
            whether it supports the plugins in the library.
          </p><p>
            There are two types of version numbers. The first is the
            version for the general plugin framework itself. Each plugin
            library includes this kind of version number. The second
            type of version applies to individual plugins. Each specific
            type of plugin has a version for its interface, so each
            plugin in a library has a type-specific version number. For
            example, a library containing a full-text parser plugin has
            a general plugin API version number, and the plugin has a
            version number specific to the full-text plugin interface.
          </p></li><li class="listitem"><p>
            The plugin API implements security restrictions.
          </p><p>
            A plugin library must be installed in a specific dedicated
            directory for which the location is controlled by the server
            and cannot be changed at runtime. Also, the library must
            contain specific symbols that identify it as a plugin
            library. The server will not load something as a plugin if
            it was not built as a plugin.
          </p></li><li class="listitem"><p>
            Plugins have access to server services.
          </p><p>
            The services interface exposes server functionality that
            plugins can access using ordinary function calls. For
            details, see <a class="xref" href="extending-mysql.html#component-plugin-services" title="28.3 MySQL Services for Components and Plugins">Section 28.3, “MySQL Services for Components and Plugins”</a>.
</p></li></ul>
</div>
<p>
        In some respects, the server plugin API is similar to the older
        user-defined function (UDF) API that it supersedes, but the
        plugin API has several advantages over the older interface. For
        example, UDFs had no versioning information. Also, the newer
        plugin interface eliminates the security issues of the older UDF
        interface. The older interface for writing nonplugin UDFs
        permitted libraries to be loaded from any directory searched by
        the system's dynamic linker, and the symbols that identified the
        UDF library were relatively nonspecific.
      </p><p>
        The client plugin API has similar architectural characteristics,
        but client plugins have no direct access to the server the way
        server plugins do.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="plugin-api-components"></a>28.2.3 Plugin API Components</h3>

</div>

</div>

</div>
<p>
        The server plugin implementation comprises several components.
      </p><p>
        SQL statements:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <a class="link" href="sql-syntax.html#install-plugin" title="13.7.4.4 INSTALL PLUGIN Syntax"><code class="literal">INSTALL PLUGIN</code></a> registers a
            plugin in the <code class="literal">mysql.plugin</code> table and
            loads the plugin code.
          </p></li><li class="listitem"><p>
            <a class="link" href="sql-syntax.html#uninstall-plugin" title="13.7.4.6 UNINSTALL PLUGIN Syntax"><code class="literal">UNINSTALL PLUGIN</code></a> unregisters
            a plugin from the <code class="literal">mysql.plugin</code> table and
            unloads the plugin code.
          </p></li><li class="listitem"><p>
            The <code class="literal">WITH PARSER</code> clause for full-text
            index creation associates a full-text parser plugin with a
            given <code class="literal">FULLTEXT</code> index.
          </p></li><li class="listitem"><p>
            <a class="link" href="sql-syntax.html#show-plugins" title="13.7.6.25 SHOW PLUGINS Syntax"><code class="literal">SHOW PLUGINS</code></a> displays
            information about server plugins.
</p></li></ul>
</div>
<p>
        Command-line options and system variables:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            The <a class="link" href="server-administration.html#option_mysqld_plugin-load"><code class="option">--plugin-load</code></a> option
            enables plugins to be loaded at server startup time.
          </p></li><li class="listitem"><p>
            The <a class="link" href="server-administration.html#sysvar_plugin_dir"><code class="literal">plugin_dir</code></a> system
            variable indicates the location of the directory where all
            plugins must be installed. The value of this variable can be
            specified at server startup with a
            <a class="link" href="server-administration.html#sysvar_plugin_dir"><code class="option">--plugin_dir=<em class="replaceable"><code>dir_name</code></em></code></a>
            option. <a class="link" href="programs.html#mysql-config" title="4.7.1 mysql_config — Display Options for Compiling Clients"><span class="command"><strong>mysql_config --plugindir</strong></span></a> displays
            the default plugin directory path name.
</p></li></ul>
</div>
<p>
        For additional information about plugin loading, see
        <a class="xref" href="server-administration.html#server-plugin-loading" title="5.6.1 Installing and Uninstalling Plugins">Section 5.6.1, “Installing and Uninstalling Plugins”</a>.
      </p><p>
        Plugin-related tables:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            The <a class="link" href="information-schema.html#plugins-table" title="24.15 The INFORMATION_SCHEMA PLUGINS Table"><code class="literal">INFORMATION_SCHEMA.PLUGINS</code></a>
            table contains plugin information.
          </p></li><li class="listitem"><p>
            The <code class="literal">mysql.plugin</code> table lists each plugin
            that was installed with <a class="link" href="sql-syntax.html#install-plugin" title="13.7.4.4 INSTALL PLUGIN Syntax"><code class="literal">INSTALL
            PLUGIN</code></a> and is required for plugin use. For new
            MySQL installations, this table is created during the
            installation process.
</p></li></ul>
</div>
<p>
        The client plugin implementation is simpler:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            For the <a class="link" href="connectors-apis.html#mysql-options" title="27.7.7.50 mysql_options()"><code class="literal">mysql_options()</code></a> C
            API function, the <code class="literal">MYSQL_DEFAULT_AUTH</code> and
            <code class="literal">MYSQL_PLUGIN_DIR</code> options enable client
            programs to load authentication plugins.
          </p></li><li class="listitem"><p>
            There are C API functions that enable management of client
            plugins.
</p></li></ul>
</div>
<p>
        To examine how MySQL implements plugins, consult the following
        source files in a MySQL source distribution:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            In the <code class="filename">include/mysql</code> directory,
            <code class="filename">plugin.h</code> exposes the public plugin API.
            This file should be examined by anyone who wants to write a
            plugin library.
            <code class="filename">plugin_<em class="replaceable"><code>xxx</code></em>.h</code>
            files provide additional information that pertains to
            specific types of plugins.
            <code class="filename">client_plugin.h</code> contains information
            specific to client plugins.
          </p></li><li class="listitem"><p>
            In the <code class="filename">sql</code> directory,
            <code class="filename">sql_plugin.h</code> and
            <code class="filename">sql_plugin.cc</code> comprise the internal
            plugin implementation. <code class="filename">sql_acl.cc</code> is
            where the server uses authentication plugins. These files
            need not be consulted by plugin developers. They may be of
            interest for those who want to know more about how the
            server handles plugins.
          </p></li><li class="listitem"><p>
            In the <code class="filename">sql-common</code> directory,
            <code class="filename">client_plugin.h</code> implements the C API
            client plugin functions, and <code class="literal">client.c</code>
            implements client authentication support. These files need
            not be consulted by plugin developers. They may be of
            interest for those who want to know more about how the
            server handles plugins.
</p></li></ul>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="writing-plugins"></a>28.2.4 Writing Plugins</h3>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="extending-mysql.html#writing-plugins-overview">28.2.4.1 Overview of Plugin Writing</a></span></dt><dt><span class="section"><a href="extending-mysql.html#plugin-data-structures">28.2.4.2 Plugin Data Structures</a></span></dt><dt><span class="section"><a href="extending-mysql.html#compiling-plugin-libraries">28.2.4.3 Compiling and Installing Plugin Libraries</a></span></dt><dt><span class="section"><a href="extending-mysql.html#writing-full-text-plugins">28.2.4.4 Writing Full-Text Parser Plugins</a></span></dt><dt><span class="section"><a href="extending-mysql.html#writing-daemon-plugins">28.2.4.5 Writing Daemon Plugins</a></span></dt><dt><span class="section"><a href="extending-mysql.html#writing-information-schema-plugins">28.2.4.6 Writing INFORMATION_SCHEMA Plugins</a></span></dt><dt><span class="section"><a href="extending-mysql.html#writing-semisynchronous-replication-plugins">28.2.4.7 Writing Semisynchronous Replication Plugins</a></span></dt><dt><span class="section"><a href="extending-mysql.html#writing-audit-plugins">28.2.4.8 Writing Audit Plugins</a></span></dt><dt><span class="section"><a href="extending-mysql.html#writing-authentication-plugins">28.2.4.9 Writing Authentication Plugins</a></span></dt><dt><span class="section"><a href="extending-mysql.html#writing-password-validation-plugins">28.2.4.10 Writing Password-Validation Plugins</a></span></dt><dt><span class="section"><a href="extending-mysql.html#writing-protocol-trace-plugins">28.2.4.11 Writing Protocol Trace Plugins</a></span></dt><dt><span class="section"><a href="extending-mysql.html#writing-keyring-plugins">28.2.4.12 Writing Keyring Plugins</a></span></dt></dl>
</div>
<p>
        To create a plugin library, you must provide the required
        descriptor information that indicates what plugins the library
        file contains, and write the interface functions for each
        plugin.
      </p><p>
        Every server plugin must have a general descriptor that provides
        information to the plugin API, and a type-specific descriptor
        that provides information about the plugin interface for a given
        type of plugin. The structure of the general descriptor is the
        same for all plugin types. The structure of the type-specific
        descriptor varies among plugin types and is determined by the
        requirements of what the plugin needs to do. The server plugin
        interface also enables plugins to expose status and system
        variables. These variables become visible through the
        <a class="link" href="sql-syntax.html#show-status" title="13.7.6.35 SHOW STATUS Syntax"><code class="literal">SHOW STATUS</code></a> and
        <a class="link" href="sql-syntax.html#show-variables" title="13.7.6.39 SHOW VARIABLES Syntax"><code class="literal">SHOW VARIABLES</code></a> statements and the
        corresponding <code class="literal">INFORMATION_SCHEMA</code> tables.
      </p><p>
        For client-side plugins, the architecture is a bit different.
        Each plugin must have a descriptor, but there is no division
        into separate general and type-specific descriptors. Instead,
        the descriptor begins with a fixed set of members common to all
        client plugin types, and the common members are followed by any
        additional members required to implement the specific plugin
        type.
      </p><p>
        You can write plugins in C or C++ (or another language that can
        use C calling conventions). Plugins are loaded and unloaded
        dynamically, so your operating system must support dynamic
        loading and you must have compiled the calling application
        dynamically (not statically). For server plugins, this means
        that <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> must be linked dynamically.
      </p><p>
        A server plugin contains code that becomes part of the running
        server, so when you write the plugin, you are bound by any and
        all constraints that otherwise apply to writing server code. For
        example, you may have problems if you attempt to use functions
        from the <code class="literal">libstdc++</code> library. These constraints
        may change in future versions of the server, so it is possible
        that server upgrades will require revisions to plugins
        originally written for older servers. For information about
        these constraints, see
        <a class="xref" href="installing.html#source-configuration-options" title="2.9.4 MySQL Source-Configuration Options">Section 2.9.4, “MySQL Source-Configuration Options”</a>, and
        <a class="xref" href="installing.html#compilation-problems" title="2.9.5 Dealing with Problems Compiling MySQL">Section 2.9.5, “Dealing with Problems Compiling MySQL”</a>.
      </p><p>
        Client plugin writers should avoid dependencies on what symbols
        the calling application has because you cannot be sure what
        applications will use the plugin.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="writing-plugins-overview"></a>28.2.4.1 Overview of Plugin Writing</h4>
</div>
</div>
</div>
<p>
          The following procedure provides an overview of the steps
          needed to create a plugin library. The next sections provide
          additional details on setting plugin data structures and
          writing specific types of plugins.
</p>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
              In the plugin source file, include the header files that
              the plugin library needs. The
              <code class="filename">plugin.h</code> file is required, and the
              library might require other files as well. For example:
            </p><pre class="programlisting">
#include &lt;stdlib.h&gt;
#include &lt;ctype.h&gt;
#include &lt;mysql/plugin.h&gt;
</pre></li><li class="listitem"><p>
              Set up the descriptor information for the plugin library
              file. For server plugins, write the library descriptor,
              which must contain the general plugin descriptor for each
              server plugin in the file. For more information, see
              <a class="xref" href="extending-mysql.html#server-plugin-descriptors" title="28.2.4.2.1 Server Plugin Library and Plugin Descriptors">Section 28.2.4.2.1, “Server Plugin Library and Plugin Descriptors”</a>. In addition,
              set up the type-specific descriptor for each server plugin
              in the library. Each plugin's general descriptor points to
              its type-specific descriptor.
            </p><p>
              For client plugins, write the client descriptor. For more
              information, see
              <a class="xref" href="extending-mysql.html#client-plugin-descriptors" title="28.2.4.2.3 Client Plugin Descriptors">Section 28.2.4.2.3, “Client Plugin Descriptors”</a>.
            </p></li><li class="listitem"><p>
              Write the plugin interface functions for each plugin. For
              example, each plugin's general plugin descriptor points to
              the initialization and deinitialization functions that the
              server should invoke when it loads and unloads the plugin.
              The plugin's type-specific description may also point to
              interface functions.
            </p></li><li class="listitem"><p>
              For server plugins, set up the status and system
              variables, if there are any.
            </p></li><li class="listitem"><p>
              Compile the plugin library as a shared library and install
              it in the plugin directory. For more information, see
              <a class="xref" href="extending-mysql.html#compiling-plugin-libraries" title="28.2.4.3 Compiling and Installing Plugin Libraries">Section 28.2.4.3, “Compiling and Installing Plugin Libraries”</a>.
            </p></li><li class="listitem"><p>
              For server plugins, register the plugin with the server.
              For more information, see
              <a class="xref" href="server-administration.html#server-plugin-loading" title="5.6.1 Installing and Uninstalling Plugins">Section 5.6.1, “Installing and Uninstalling Plugins”</a>.
            </p></li><li class="listitem"><p>
              Test the plugin to verify that it works properly.
</p></li></ol>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="plugin-data-structures"></a>28.2.4.2 Plugin Data Structures</h4>

</div>

</div>

</div>
<p>
          A plugin library file includes descriptor information to
          indicate what plugins it contains.
        </p><p>
          If the plugin library contains any server plugins, it must
          include the following descriptor information:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              A library descriptor indicates the general server plugin
              API version number used by the library and contains a
              general plugin descriptor for each server plugin in the
              library. To provide the framework for this descriptor,
              invoke two macros from the <code class="filename">plugin.h</code>
              header file:
            </p><pre class="programlisting">
mysql_declare_plugin(<em class="replaceable"><code>name</code></em>)
 <em class="replaceable"><code>... one or more server plugin descriptors here ...</code></em>
mysql_declare_plugin_end;
</pre><p>
              The macros expand to provide a declaration for the API
              version automatically. You must provide the plugin
              descriptors.
            </p></li><li class="listitem"><p>
              Within the library descriptor, each general server plugin
              is described by a <code class="literal">st_mysql_plugin</code>
              structure. This plugin descriptor structure contains
              information that is common to every type of server plugin:
              A value that indicates the plugin type; the plugin name,
              author, description, and license type; pointers to the
              initialization and deinitialization functions that the
              server invokes when it loads and unloads the plugin, and
              pointers to any status or system variables the plugin
              implements.
            </p></li><li class="listitem"><p>
              Each general server plugin descriptor within the library
              descriptor also contains a pointer to a type-specific
              plugin descriptor. The structure of the type-specific
              descriptors varies from one plugin type to another because
              each type of plugin can have its own API. A type-specific
              plugin descriptor contains a type-specific API version
              number and pointers to the functions that are needed to
              implement that plugin type. For example, a full-text
              parser plugin has initialization and deinitialization
              functions, and a main parsing function. The server invokes
              these functions when it uses the plugin to parse text.
</p></li></ul>
</div>
<p>
          The plugin library also contains the interface functions that
          are referenced by the general and type-specific descriptors
          for each plugin in the library.
        </p><p>
          If the plugin library contains a client plugin, it must
          include a descriptor for the plugin. The descriptor begins
          with a fixed set of members common to all client plugins,
          followed by any members specific to the plugin type. To
          provide the descriptor framework, invoke two macros from the
          <code class="filename">client_plugin.h</code> header file:
        </p><pre class="programlisting">
mysql_declare_client_plugin(<em class="replaceable"><code>plugin_type</code></em>)
   ... <em class="replaceable"><code>members common to all client plugins</code></em> ...
   ... <em class="replaceable"><code>type-specific extra members</code></em> ...
mysql_end_client_plugin;
</pre><p>
          The plugin library also contains any interface functions
          referenced by the client descriptor.
        </p><p>
          The <code class="literal">mysql_declare_plugin()</code> and
          <code class="literal">mysql_declare_client_plugin()</code> macros differ
          somewhat in how they can be invoked, which has implications
          for the contents of plugin libraries. The following guidelines
          summarize the rules:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              <code class="literal">mysql_declare_plugin()</code> and
              <code class="literal">mysql_declare_client_plugin()</code> can both
              be used in the same source file, which means that a plugin
              library can contain both server and client plugins.
              However, each of <code class="literal">mysql_declare_plugin()</code>
              and <code class="literal">mysql_declare_client_plugin()</code> can
              be used at most once.
            </p></li><li class="listitem"><p>
              <code class="literal">mysql_declare_plugin()</code> permits multiple
              server plugin declarations, so a plugin library can
              contain multiple server plugins.
            </p></li><li class="listitem"><p>
              <code class="literal">mysql_declare_client_plugin()</code> permits
              only a single client plugin declaration. To create
              multiple client plugins, separate plugin libraries must be
              used.
</p></li></ul>
</div>
<p>
          When a client program looks for a client plugin that is in a
          plugin library and not built into
          <code class="literal">libmysqlclient</code>, it looks for a file with a
          base name that is the same as the plugin name. For example, if
          a program needs to use a client authentication plugin named
          <code class="literal">auth_xxx</code> on a system that uses
          <code class="filename">.so</code> as the library suffix, it looks in
          the file named <code class="filename">auth_xxx.so</code>. (On OS X, the
          program looks first for <code class="filename">auth_xxx.dylib</code>,
          then for <code class="filename">auth_xxx.so</code>.) For this reason,
          if a plugin library contains a client plugin, the library must
          have the same base name as that plugin.
        </p><p>
          The same is not true for a library that contains server
          plugins. The <a class="link" href="server-administration.html#option_mysqld_plugin-load"><code class="option">--plugin-load</code></a>
          option and the <a class="link" href="sql-syntax.html#install-plugin" title="13.7.4.4 INSTALL PLUGIN Syntax"><code class="literal">INSTALL PLUGIN</code></a>
          statement provide the library file name explicitly, so there
          need be no explicit relationship between the library name and
          the name of any server plugins it contains.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="server-plugin-descriptors"></a>28.2.4.2.1 Server Plugin Library and Plugin Descriptors</h5>
</div>
</div>
</div>
<p>
            Every plugin library that contains server plugins must
            include a library descriptor that contains the general
            plugin descriptor for each server plugin in the file. This
            section discusses how to write the library and general
            descriptors for server plugins.
          </p><p>
            The library descriptor must define two symbols:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                <code class="literal">_mysql_plugin_interface_version_</code>
                specifies the version number of the general plugin
                framework. This is given by the
                <code class="literal">MYSQL_PLUGIN_INTERFACE_VERSION</code>
                symbol, which is defined in the
                <code class="filename">plugin.h</code> file.
              </p></li><li class="listitem"><p>
                <code class="literal">_mysql_plugin_declarations_</code> defines
                an array of plugin declarations, terminated by a
                declaration with all members set to 0. Each declaration
                is an instance of the <code class="literal">st_mysql_plugin</code>
                structure (also defined in
                <code class="filename">plugin.h</code>). There must be one of
                these for each server plugin in the library.
</p></li></ul>
</div>
<p>
            If the server does not find those two symbols in a library,
            it does not accept it as a legal plugin library and rejects
            it with an error. This prevents use of a library for plugin
            purposes unless it was built specifically as a plugin
            library.
          </p><p>
            The conventional way to define the two required symbols is
            by using the <code class="literal">mysql_declare_plugin()</code> and
            <code class="literal">mysql_declare_plugin_end</code> macros from the
            <code class="filename">plugin.h</code> file:
          </p><pre class="programlisting">
mysql_declare_plugin(<em class="replaceable"><code>name</code></em>)
 <em class="replaceable"><code>... one or more server plugin descriptors here ...</code></em>
mysql_declare_plugin_end;
</pre><p>
            Each server plugin must have a general descriptor that
            provides information to the server plugin API. The general
            descriptor has the same structure for all plugin types. The
            <code class="literal">st_mysql_plugin</code> structure in the
            <code class="filename">plugin.h</code> file defines this descriptor:
          </p><pre class="programlisting">
struct st_mysql_plugin
{
  int type;             /* the plugin type (a MYSQL_XXX_PLUGIN value)   */
  void *info;           /* pointer to type-specific plugin descriptor   */
  const char *name;     /* plugin name                                  */
  const char *author;   /* plugin author (for I_S.PLUGINS)              */
  const char *descr;    /* general descriptive text (for I_S.PLUGINS)   */
  int license;          /* the plugin license (PLUGIN_LICENSE_XXX)      */
  int (*init)(void *);  /* the function to invoke when plugin is loaded */
  int (*deinit)(void *);/* the function to invoke when plugin is unloaded */
  unsigned int version; /* plugin version (for I_S.PLUGINS)             */
  struct st_mysql_show_var *status_vars;
  struct st_mysql_sys_var **system_vars;
  void * __reserved1;   /* reserved for dependency checking             */
  unsigned long flags;  /* flags for plugin */
};
</pre><p>
            The <code class="literal">st_mysql_plugin</code> descriptor structure
            members are used as follows. <code class="literal">char *</code>
            members should be specified as null-terminated strings.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                <code class="literal">type</code>: The plugin type. This must be
                one of the plugin-type values from
                <code class="filename">plugin.h</code>:
              </p><pre class="programlisting">
/*
  The allowable types of plugins
*/
#define MYSQL_UDF_PLUGIN             0  /* User-defined function        */
#define MYSQL_STORAGE_ENGINE_PLUGIN  1  /* Storage Engine               */
#define MYSQL_FTPARSER_PLUGIN        2  /* Full-text parser plugin      */
#define MYSQL_DAEMON_PLUGIN          3  /* The daemon/raw plugin type */
#define MYSQL_INFORMATION_SCHEMA_PLUGIN  4  /* The I_S plugin type */
#define MYSQL_AUDIT_PLUGIN           5  /* The Audit plugin type        */
#define MYSQL_REPLICATION_PLUGIN     6  /* The replication plugin type */
#define MYSQL_AUTHENTICATION_PLUGIN  7  /* The authentication plugin type */
...
</pre><p>
                For example, for a full-text parser plugin, the
                <code class="literal">type</code> value is
                <code class="literal">MYSQL_FTPARSER_PLUGIN</code>.
              </p></li><li class="listitem"><p>
                <code class="literal">info</code>: A pointer to the type-specific
                descriptor for the plugin. This descriptor's structure
                depends on the particular type of plugin, unlike that of
                the general plugin descriptor structure. For
                version-control purposes, the first member of the
                type-specific descriptor for every plugin type is
                expected to be the interface version for the type. This
                enables the server to check the type-specific version
                for every plugin no matter its type. Following the
                version number, the descriptor includes any other
                members needed, such as callback functions and other
                information needed by the server to invoke the plugin
                properly. Later sections on writing particular types of
                server plugins describe the structure of their
                type-specific descriptors.
              </p></li><li class="listitem"><p>
                <code class="literal">name</code>: A string that gives the plugin
                name. This is the name that will be listed in the
                <code class="literal">mysql.plugin</code> table and by which you
                refer to the plugin in SQL statements such as
                <a class="link" href="sql-syntax.html#install-plugin" title="13.7.4.4 INSTALL PLUGIN Syntax"><code class="literal">INSTALL PLUGIN</code></a> and
                <a class="link" href="sql-syntax.html#uninstall-plugin" title="13.7.4.6 UNINSTALL PLUGIN Syntax"><code class="literal">UNINSTALL PLUGIN</code></a>, or with
                the <a class="link" href="server-administration.html#option_mysqld_plugin-load"><code class="option">--plugin-load</code></a> option.
                The name is also visible in the
                <a class="link" href="information-schema.html#plugins-table" title="24.15 The INFORMATION_SCHEMA PLUGINS Table"><code class="literal">INFORMATION_SCHEMA.PLUGINS</code></a>
                table or the output from <a class="link" href="sql-syntax.html#show-plugins" title="13.7.6.25 SHOW PLUGINS Syntax"><code class="literal">SHOW
                PLUGINS</code></a>.
              </p><p>
                The plugin name should not begin with the name of any
                server option. If it does, the server will fail to
                initialize it. For example, the server has a
                <a class="link" href="server-administration.html#option_mysqld_socket"><code class="option">--socket</code></a> option, so you
                should not use a plugin name such as
                <code class="literal">socket</code>,
                <code class="literal">socket_plugin</code>, and so forth.
              </p></li><li class="listitem"><p>
                <code class="literal">author</code>: A string naming the plugin
                author. This can be whatever you like.
              </p></li><li class="listitem"><p>
                <code class="literal">desc</code>: A string that provides a
                general description of the plugin. This can be whatever
                you like.
              </p></li><li class="listitem"><p>
                <code class="literal">license</code>: The plugin license type. The
                value can be one of
                <code class="literal">PLUGIN_LICENSE_PROPRIETARY</code>,
                <code class="literal">PLUGIN_LICENSE_GPL</code>, or
                <code class="literal">PLUGIN_LICENSE_BSD</code>.
              </p></li><li class="listitem"><p>
                <code class="literal">init</code>: A once-only initialization
                function, or <code class="literal">NULL</code> if there is no such
                function. The server executes this function when it
                loads the plugin, which happens for
                <a class="link" href="sql-syntax.html#install-plugin" title="13.7.4.4 INSTALL PLUGIN Syntax"><code class="literal">INSTALL PLUGIN</code></a> or, for
                plugins listed in the <code class="literal">mysql.plugin</code>
                table, at server startup. The function takes one
                argument that points to the internal structure used to
                identify the plugin. It returns zero for success and
                nonzero for failure.
              </p></li><li class="listitem"><p>
                <code class="literal">deinit</code>: A once-only deinitialization
                function, or <code class="literal">NULL</code> if there is no such
                function. The server executes this function when it
                unloads the plugin, which happens for
                <a class="link" href="sql-syntax.html#uninstall-plugin" title="13.7.4.6 UNINSTALL PLUGIN Syntax"><code class="literal">UNINSTALL PLUGIN</code></a> or, for
                plugins listed in the <code class="literal">mysql.plugin</code>
                table, at server shutdown. The function takes one
                argument that points to the internal structure used to
                identify the plugin It returns zero for success and
                nonzero for failure.
              </p></li><li class="listitem"><p>
                <code class="literal">version</code>: The plugin version number.
                When the plugin is installed, this value can be
                retrieved from the
                <a class="link" href="information-schema.html#plugins-table" title="24.15 The INFORMATION_SCHEMA PLUGINS Table"><code class="literal">INFORMATION_SCHEMA.PLUGINS</code></a>
                table. The value includes major and minor numbers. If
                you write the value as a hex constant, the format is
                <code class="literal">0x<em class="replaceable"><code>MMNN</code></em></code>,
                where <em class="replaceable"><code>MM</code></em> and
                <code class="literal">NN</code> are the major and minor numbers,
                respectively. For example, <code class="literal">0x0302</code>
                represents version 3.2.
              </p></li><li class="listitem"><p>
                <code class="literal">status_vars</code>: A pointer to a structure
                for status variables associated with the plugin, or
                <code class="literal">NULL</code> if there are no such variables.
                When the plugin is installed, these variables are
                displayed in the output of the <a class="link" href="sql-syntax.html#show-status" title="13.7.6.35 SHOW STATUS Syntax"><code class="literal">SHOW
                STATUS</code></a> statement.
              </p><p>
                The <code class="literal">status_vars</code> member, if not
                <code class="literal">NULL</code>, points to an array of
                <code class="literal">st_mysql_show_var</code> structures that
                describe status variables. See
                <a class="xref" href="extending-mysql.html#plugin-status-system-variables" title="28.2.4.2.2 Server Plugin Status and System Variables">Section 28.2.4.2.2, “Server Plugin Status and System Variables”</a>.
              </p></li><li class="listitem"><p>
                <code class="literal">system_vars</code>: A pointer to a structure
                for system variables associated with the plugin, or
                <code class="literal">NULL</code> if there are no such variables.
                These options and system variables can be used to help
                initialize variables within the plugin. When the plugin
                is installed, these variables are displayed in the
                output of the <a class="link" href="sql-syntax.html#show-variables" title="13.7.6.39 SHOW VARIABLES Syntax"><code class="literal">SHOW
                VARIABLES</code></a> statement.
              </p><p>
                The <code class="literal">system_vars</code> member, if not
                <code class="literal">NULL</code>, points to an array of
                <code class="literal">st_mysql_sys_var</code> structures that
                describe system variables. See
                <a class="xref" href="extending-mysql.html#plugin-status-system-variables" title="28.2.4.2.2 Server Plugin Status and System Variables">Section 28.2.4.2.2, “Server Plugin Status and System Variables”</a>.
              </p></li><li class="listitem"><p>
                <code class="literal">__reserved1</code>: A placeholder for the
                future. It should be set to <code class="literal">NULL</code>.
              </p></li><li class="listitem"><p>
                <code class="literal">flags</code>: Plugin flags. Individual bits
                correspond to different flags. The value should be set
                to the OR of the applicable flags. These flags are
                available:
              </p><pre class="programlisting">
#define PLUGIN_OPT_NO_INSTALL   1UL   /* Not dynamically loadable */
#define PLUGIN_OPT_NO_UNINSTALL 2UL   /* Not dynamically unloadable */
</pre><p>
                <code class="literal">PLUGIN_OPT_NO_INSTALL</code> indicates that
                the plugin cannot be loaded at runtime with the
                <a class="link" href="sql-syntax.html#install-plugin" title="13.7.4.4 INSTALL PLUGIN Syntax"><code class="literal">INSTALL PLUGIN</code></a> statement.
                This is appropriate for plugins that must be loaded at
                server startup with the
                <a class="link" href="server-administration.html#option_mysqld_plugin-load"><code class="option">--plugin-load</code></a> option.
                <code class="literal">PLUGIN_OPT_NO_UNINSTALL</code> indicates
                that the plugin cannot be unloaded at runtime with the
                <a class="link" href="sql-syntax.html#uninstall-plugin" title="13.7.4.6 UNINSTALL PLUGIN Syntax"><code class="literal">UNINSTALL PLUGIN</code></a>
                statement.
</p></li></ul>
</div>
<p>
            The server invokes the <code class="literal">init</code> and
            <code class="literal">deinit</code> functions in the general plugin
            descriptor only when loading and unloading the plugin. They
            have nothing to do with use of the plugin such as happens
            when an SQL statement causes the plugin to be invoked.
          </p><p>
            For example, the descriptor information for a library that
            contains a single full-text parser plugin named
            <code class="literal">simple_parser</code> looks like this:
          </p><pre class="programlisting">
mysql_declare_plugin(ftexample)
{
  MYSQL_FTPARSER_PLUGIN,      /* type                            */
  &amp;simple_parser_descriptor,  /* descriptor                      */
  "simple_parser",            /* name                            */
  "Oracle Corporation",       /* author                          */
  "Simple Full-Text Parser",  /* description                     */
  PLUGIN_LICENSE_GPL,         /* plugin license                  */
  simple_parser_plugin_init,  /* init function (when loaded)     */
  simple_parser_plugin_deinit,/* deinit function (when unloaded) */
  0x0001,                     /* version                         */
  simple_status,              /* status variables                */
  simple_system_variables,    /* system variables                */
  NULL,
  0
}
mysql_declare_plugin_end;
</pre><p>
            For a full-text parser plugin, the type must be
            <code class="literal">MYSQL_FTPARSER_PLUGIN</code>. This is the value
            that identifies the plugin as being legal for use in a
            <code class="literal">WITH PARSER</code> clause when creating a
            <code class="literal">FULLTEXT</code> index. (No other plugin type is
            legal for this clause.)
          </p><p>
            <code class="filename">plugin.h</code> defines the
            <code class="literal">mysql_declare_plugin()</code> and
            <code class="literal">mysql_declare_plugin_end</code> macros like
            this:
          </p><pre class="programlisting">
#ifndef MYSQL_DYNAMIC_PLUGIN
#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \
MYSQL_PLUGIN_EXPORT int VERSION= MYSQL_PLUGIN_INTERFACE_VERSION; \
MYSQL_PLUGIN_EXPORT int PSIZE= sizeof(struct st_mysql_plugin); \
MYSQL_PLUGIN_EXPORT struct st_mysql_plugin DECLS[]= {
#else
#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \
MYSQL_PLUGIN_EXPORT int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \
MYSQL_PLUGIN_EXPORT int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin); \
MYSQL_PLUGIN_EXPORT struct st_mysql_plugin _mysql_plugin_declarations_[]= {
#endif

#define mysql_declare_plugin(NAME) \
__MYSQL_DECLARE_PLUGIN(NAME, \
                 builtin_ ## NAME ## _plugin_interface_version, \
                 builtin_ ## NAME ## _sizeof_struct_st_plugin, \
                 builtin_ ## NAME ## _plugin)

#define mysql_declare_plugin_end ,{0,0,0,0,0,0,0,0,0,0,0,0,0}}
</pre>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
              Those declarations define the
              <code class="literal">_mysql_plugin_interface_version_</code> symbol
              only if the <code class="literal">MYSQL_DYNAMIC_PLUGIN</code> symbol
              is defined. This means that
              <code class="literal">-DMYSQL_DYNAMIC_PLUGIN</code> must be provided
              as part of the compilation command to build the plugin as
              a shared library.
</p>
</div>
<p>
            When the macros are used as just shown, they expand to the
            following code, which defines both of the required symbols
            (<code class="literal">_mysql_plugin_interface_version_</code> and
            <code class="literal">_mysql_plugin_declarations_</code>):
          </p><pre class="programlisting">
int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION;
int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin);
struct st_mysql_plugin _mysql_plugin_declarations_[]= {
{
  MYSQL_FTPARSER_PLUGIN,      /* type                            */
  &amp;simple_parser_descriptor,  /* descriptor                      */
  "simple_parser",            /* name                            */
  "Oracle Corporation",       /* author                          */
  "Simple Full-Text Parser",  /* description                     */
  PLUGIN_LICENSE_GPL,         /* plugin license                  */
  simple_parser_plugin_init,  /* init function (when loaded)     */
  simple_parser_plugin_deinit,/* deinit function (when unloaded) */
  0x0001,                     /* version                         */
  simple_status,              /* status variables                */
  simple_system_variables,    /* system variables                */
  NULL,
  0
}
  ,{0,0,0,0,0,0,0,0,0,0,0,0}}
};
</pre><p>
            The preceding example declares a single plugin in the
            general descriptor, but it is possible to declare multiple
            plugins. List the declarations one after the other between
            <code class="literal">mysql_declare_plugin()</code> and
            <code class="literal">mysql_declare_plugin_end</code>, separated by
            commas.
          </p><p>
            MySQL server plugins can be written in C or C++ (or another
            language that can use C calling conventions). If you write a
            C++ plugin, one C++ feature that you should not use is
            nonconstant variables to initialize global structures.
            Members of structures such as the
            <code class="literal">st_mysql_plugin</code> structure should be
            initialized only with constant variables. The
            <code class="literal">simple_parser</code> descriptor shown earlier is
            permissible in a C++ plugin because it satisfies that
            requirement:
          </p><pre class="programlisting">
mysql_declare_plugin(ftexample)
{
  MYSQL_FTPARSER_PLUGIN,      /* type                            */
  &amp;simple_parser_descriptor,  /* descriptor                      */
  "simple_parser",            /* name                            */
  "Oracle Corporation",       /* author                          */
  "Simple Full-Text Parser",  /* description                     */
  PLUGIN_LICENSE_GPL,         /* plugin license                  */
  simple_parser_plugin_init,  /* init function (when loaded)     */
  simple_parser_plugin_deinit,/* deinit function (when unloaded) */
  0x0001,                     /* version                         */
  simple_status,              /* status variables                */
  simple_system_variables,    /* system variables                */
  NULL,
  0
}
mysql_declare_plugin_end;
</pre><p>
            Here is another valid way to write the general descriptor.
            It uses constant variables to indicate the plugin name,
            author, and description:
          </p><pre class="programlisting">
const char *simple_parser_name = "simple_parser";
const char *simple_parser_author = "Oracle Corporation";
const char *simple_parser_description = "Simple Full-Text Parser";

mysql_declare_plugin(ftexample)
{
  MYSQL_FTPARSER_PLUGIN,      /* type                            */
  &amp;simple_parser_descriptor,  /* descriptor                      */
  simple_parser_name,         /* name                            */
  simple_parser_author,       /* author                          */
  simple_parser_description,  /* description                     */
  PLUGIN_LICENSE_GPL,         /* plugin license                  */
  simple_parser_plugin_init,  /* init function (when loaded)     */
  simple_parser_plugin_deinit,/* deinit function (when unloaded) */
  0x0001,                     /* version                         */
  simple_status,              /* status variables                */
  simple_system_variables,    /* system variables                */
  NULL,
  0
}
mysql_declare_plugin_end;
</pre><p>
            However, the following general descriptor is invalid. It
            uses structure members to indicate the plugin name, author,
            and description, but structures are not considered constant
            initializers in C++:
          </p><pre class="programlisting">
typedef struct
{
  const char *name;
  const char *author;
  const char *description;
} plugin_info;

plugin_info parser_info = {
  "simple_parser",
  "Oracle Corporation",
  "Simple Full-Text Parser"
};

mysql_declare_plugin(ftexample)
{
  MYSQL_FTPARSER_PLUGIN,      /* type                            */
  &amp;simple_parser_descriptor,  /* descriptor                      */
  parser_info.name,           /* name                            */
  parser_info.author,         /* author                          */
  parser_info.description,    /* description                     */
  PLUGIN_LICENSE_GPL,         /* plugin license                  */
  simple_parser_plugin_init,  /* init function (when loaded)     */
  simple_parser_plugin_deinit,/* deinit function (when unloaded) */
  0x0001,                     /* version                         */
  simple_status,              /* status variables                */
  simple_system_variables,    /* system variables                */
  NULL,
  0
}
mysql_declare_plugin_end;
</pre>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="plugin-status-system-variables"></a>28.2.4.2.2 Server Plugin Status and System Variables</h5>

</div>

</div>

</div>
<p>
            The server plugin interface enables plugins to expose status
            and system variables using the
            <code class="literal">status_vars</code> and
            <code class="literal">system_vars</code> members of the general plugin
            descriptor.
          </p><p>
            The <code class="literal">status_vars</code> member of the general
            plugin descriptor, if not 0, points to an array of
            <code class="literal">st_mysql_show_var</code> structures, each of
            which describes one status variable, followed by a structure
            with all members set to 0. The
            <code class="literal">st_mysql_show_var</code> structure has this
            definition:
          </p><pre class="programlisting">
struct st_mysql_show_var {
  const char *name;
  char *value;
  enum enum_mysql_show_type type;
};
</pre><p>
            The following table shows the permissible status variable
            <code class="literal">type</code> values and what the corresponding
            variable should be.
</p>
<div class="table">
<a name="idm139899456174272"></a><p class="title"><b>Table 28.1 Server Plugin Status Variable Types</b></p>
<div class="table-contents">
<table><col width="30%"><col width="70%"><thead><tr>
                <th scope="col">Variable Type</th>
                <th scope="col">Meaning</th>
              </tr></thead><tbody><tr>
                <td scope="row"><code class="literal">SHOW_BOOL</code></td>
                <td>Pointer to a boolean variable</td>
              </tr><tr>
                <td scope="row"><code class="literal">SHOW_INT</code></td>
                <td>Pointer to an integer variable</td>
              </tr><tr>
                <td scope="row"><code class="literal">SHOW_LONG</code></td>
                <td>Pointer to a long integer variable</td>
              </tr><tr>
                <td scope="row"><code class="literal">SHOW_LONGLONG</code></td>
                <td>Pointer to a longlong integer variable</td>
              </tr><tr>
                <td scope="row"><code class="literal">SHOW_CHAR</code></td>
                <td>A string</td>
              </tr><tr>
                <td scope="row"><code class="literal">SHOW_CHAR_PTR</code></td>
                <td>Pointer to a string</td>
              </tr><tr>
                <td scope="row"><code class="literal">SHOW_ARRAY</code></td>
                <td>Pointer to another <code class="literal">st_mysql_show_var</code> array</td>
              </tr><tr>
                <td scope="row"><code class="literal">SHOW_FUNC</code></td>
                <td>Pointer to a function</td>
              </tr><tr>
                <td scope="row"><code class="literal">SHOW_DOUBLE</code></td>
                <td>Pointer to a double</td>
</tr></tbody></table>
</div>

</div>
<br class="table-break"><p>
            For the <code class="literal">SHOW_FUNC</code> type, the function is
            called and fills in its <code class="literal">out</code> parameter,
            which then provides information about the variable to be
            displayed. The function has this signature:
          </p><pre class="programlisting">
#define SHOW_VAR_FUNC_BUFF_SIZE 1024

typedef int (*mysql_show_var_func) (void *thd,
                                    struct st_mysql_show_var *out,
                                    char *buf);
</pre><p>
            The <code class="literal">system_vars</code> member, if not 0, points
            to an array of <code class="literal">st_mysql_sys_var</code>
            structures, each of which describes one system variable
            (which can also be set from the command-line or
            configuration file), followed by a structure with all
            members set to 0. The <code class="literal">st_mysql_sys_var</code>
            structure is defined as follows:
          </p><pre class="programlisting">
struct st_mysql_sys_var {
 int flags;
 const char *name, *comment;
 int (*check)(THD*, struct st_mysql_sys_var *, void*, st_mysql_value*);
 void (*update)(THD*, struct st_mysql_sys_var *, void*, const void*);
};
</pre><p>
            Additional fields are append as required depending upon the
            flags.
          </p><p>
            For convenience, a number of macros are defined that make
            creating new system variables within a plugin much simpler.
          </p><p>
            Throughout the macros, the following fields are available:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                <code class="literal">name</code>: An unquoted identifier for the
                system variable.
              </p></li><li class="listitem"><p>
                <code class="literal">varname</code>: The identifier for the
                static variable. Where not available, it is the same as
                the <code class="literal">name</code> field.
              </p></li><li class="listitem"><p>
                <code class="literal">opt</code>: Additional use flags for the
                system variable. The following table shows the
                permissible flags.
</p>
<div class="table">
<a name="idm139899456128752"></a><p class="title"><b>Table 28.2 Server Plugin System Variable Flags</b></p>
<div class="table-contents">
<table><col width="25%"><col width="75%"><thead><tr>
                    <th scope="col">Flag Value</th>
                    <th scope="col">Description</th>
                  </tr></thead><tbody><tr>
                    <td scope="row"><code class="literal">PLUGIN_VAR_READONLY</code></td>
                    <td>The system variable is read only</td>
                  </tr><tr>
                    <td scope="row"><code class="literal">PLUGIN_VAR_NOSYSVAR</code></td>
                    <td>The system variable is not user visible at runtime</td>
                  </tr><tr>
                    <td scope="row"><code class="literal">PLUGIN_VAR_NOCMDOPT</code></td>
                    <td>The system variable is not configurable from the command line</td>
                  </tr><tr>
                    <td scope="row"><code class="literal">PLUGIN_VAR_NOCMDARG</code></td>
                    <td>No argument is required at the command line (typically used for boolean
                      variables)</td>
                  </tr><tr>
                    <td scope="row"><code class="literal">PLUGIN_VAR_RQCMDARG</code></td>
                    <td>An argument is required at the command line (this is the default)</td>
                  </tr><tr>
                    <td scope="row"><code class="literal"> PLUGIN_VAR_OPCMDARG</code></td>
                    <td>An argument is optional at the command line</td>
                  </tr><tr>
                    <td scope="row"><code class="literal">PLUGIN_VAR_MEMALLOC</code></td>
                    <td>Used for string variables; indicates that memory is to be allocated for
                      storage of the string</td>
</tr></tbody></table>
</div>

</div>
<br class="table-break"></li><li class="listitem"><p>
                <code class="literal">comment</code>: A descriptive comment to be
                displayed in the server help message.
                <code class="literal">NULL</code> if this variable is to be
                hidden.
              </p></li><li class="listitem"><p>
                <code class="literal">check</code>: The check function,
                <code class="literal">NULL</code> for default.
              </p></li><li class="listitem"><p>
                <code class="literal">update</code>: The update function,
                <code class="literal">NULL</code> for default.
              </p></li><li class="listitem"><p>
                <code class="literal">default</code>: The variable default value.
              </p></li><li class="listitem"><p>
                <code class="literal">minimum</code>: The variable minimum value.
              </p></li><li class="listitem"><p>
                <code class="literal">maximum</code>: The variable maximum value.
              </p></li><li class="listitem"><p>
                <code class="literal">blocksize</code>: The variable block size.
                When the value is set, it is rounded to the nearest
                multiple of <code class="literal">blocksize</code>.
</p></li></ul>
</div>
<p>
            A system variable may be accessed either by using the static
            variable directly or by using the
            <code class="literal">SYSVAR()</code>accessor macro. The
            <code class="literal">SYSVAR()</code> macro is provided for
            completeness. Usually it should be used only when the code
            cannot directly access the underlying variable.
          </p><p>
            For example:
          </p><pre class="programlisting">
static int my_foo;
static MYSQL_SYSVAR_INT(foo_var, my_foo,
                        PLUGIN_VAR_RQCMDARG, "foo comment",
                        NULL, NULL, 0, 0, INT_MAX, 0);
 ...
   SYSVAR(foo_var)= value;
   value= SYSVAR(foo_var);
   my_foo= value;
   value= my_foo;
</pre><p>
            Session variables may be accessed only through the
            <code class="literal">THDVAR()</code> accessor macro. For example:
          </p><pre class="programlisting">
static MYSQL_THDVAR_BOOL(some_flag,
                         PLUGIN_VAR_NOCMDARG, "flag comment",
                         NULL, NULL, FALSE);
 ...
   if (THDVAR(thd, some_flag))
   {
     do_something();
     THDVAR(thd, some_flag)= FALSE;
   }
</pre><p>
            All global and session system variables must be published to
            <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> before use. This is done by
            constructing a <code class="literal">NULL</code>-terminated array of
            the variables and linking to it in the plugin public
            interface. For example:
          </p><pre class="programlisting">
static struct st_mysql_sys_var *my_plugin_vars[]= {
  MYSQL_SYSVAR(foo_var),
  MYSQL_SYSVAR(some_flag),
  NULL
};
mysql_declare_plugin(fooplug)
{
  MYSQL_..._PLUGIN,
  &amp;plugin_data,
  "fooplug",
  "foo author",
  "This does foo!",
  PLUGIN_LICENSE_GPL,
  foo_init,
  foo_fini,
  0x0001,
  NULL,
  my_plugin_vars,
  NULL,
  0
}
mysql_declare_plugin_end;
</pre><p>
            The following convenience macros enable you to declare
            different types of system variables:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                Boolean system variables of type
                <code class="literal">bool</code>, which is a 1-byte boolean. (0 =
                <code class="literal">false</code>, 1 = <code class="literal">true</code>)
              </p><pre class="programlisting">
MYSQL_THDVAR_BOOL(name, opt, comment, check, update, default)
MYSQL_SYSVAR_BOOL(name, varname, opt, comment, check, update, default)
</pre></li><li class="listitem"><p>
                String system variables of type
                <code class="literal">char*</code>, which is a pointer to a
                null-terminated string.
              </p><pre class="programlisting">
MYSQL_THDVAR_STR(name, opt, comment, check, update, default)
MYSQL_SYSVAR_STR(name, varname, opt, comment, check, update, default)
</pre></li><li class="listitem"><p>
                Integer system variables, of which there are several
                varieties.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                    An <code class="literal">int</code> system variable, which is
                    typically a 4-byte signed word.
                  </p><pre class="programlisting">
MYSQL_THDVAR_INT(name, opt, comment, check, update, default, min, max, blk)
MYSQL_SYSVAR_INT(name, varname, opt, comment, check, update, default,
               minimum, maximum, blocksize)
</pre></li><li class="listitem"><p>
                    An <code class="literal">unsigned int</code> system variable,
                    which is typically a 4-byte unsigned word.
                  </p><pre class="programlisting">
MYSQL_THDVAR_UINT(name, opt, comment, check, update, default, min, max, blk)
MYSQL_SYSVAR_UINT(name, varname, opt, comment, check, update, default,
                minimum, maximum, blocksize)
</pre></li><li class="listitem"><p>
                    A <code class="literal">long</code> system variable, which is
                    typically either a 4- or 8-byte signed word.
                  </p><pre class="programlisting">
MYSQL_THDVAR_LONG(name, opt, comment, check, update, default, min, max, blk)
MYSQL_SYSVAR_LONG(name, varname, opt, comment, check, update, default,
                minimum, maximum, blocksize)
</pre></li><li class="listitem"><p>
                    An <code class="literal">unsigned long</code> system variable,
                    which is typically either a 4- or 8-byte unsigned
                    word.
                  </p><pre class="programlisting">
MYSQL_THDVAR_ULONG(name, opt, comment, check, update, default, min, max, blk)
MYSQL_SYSVAR_ULONG(name, varname, opt, comment, check, update, default,
                 minimum, maximum, blocksize)
</pre></li><li class="listitem"><p>
                    A <code class="literal">long long</code> system variable,
                    which is typically an 8-byte signed word.
                  </p><pre class="programlisting">
MYSQL_THDVAR_LONGLONG(name, opt, comment, check, update,
                    default, minimum, maximum, blocksize)
MYSQL_SYSVAR_LONGLONG(name, varname, opt, comment, check, update,
                    default, minimum, maximum, blocksize)
</pre></li><li class="listitem"><p>
                    An <code class="literal">unsigned long long</code> system
                    variable, which is typically an 8-byte unsigned
                    word.
                  </p><pre class="programlisting">
MYSQL_THDVAR_ULONGLONG(name, opt, comment, check, update,
                     default, minimum, maximum, blocksize)
MYSQL_SYSVAR_ULONGLONG(name, varname, opt, comment, check, update,
                     default, minimum, maximum, blocksize)
</pre></li><li class="listitem"><p>
                    A <code class="literal">double</code> system variable, which
                    is typically an 8-byte signed word.
                  </p><pre class="programlisting">
MYSQL_THDVAR_DOUBLE(name, opt, comment, check, update,
                     default, minimum, maximum, blocksize)
MYSQL_SYSVAR_DOUBLE(name, varname, opt, comment, check, update,
                     default, minimum, maximum, blocksize)
</pre></li><li class="listitem"><p>
                    An <code class="literal">unsigned long</code> system variable,
                    which is typically either a 4- or 8-byte unsigned
                    word. The range of possible values is an ordinal of
                    the number of elements in the
                    <code class="literal">typelib</code>, starting from 0.
                  </p><pre class="programlisting">
MYSQL_THDVAR_ENUM(name, opt, comment, check, update, default, typelib)
MYSQL_SYSVAR_ENUM(name, varname, opt, comment, check, update,
                default, typelib)
</pre></li><li class="listitem"><p>
                    An <code class="literal">unsigned long long</code> system
                    variable, which is typically an 8-byte unsigned
                    word. Each bit represents an element in the
                    <code class="literal">typelib</code>.
                  </p><pre class="programlisting">
MYSQL_THDVAR_SET(name, opt, comment, check, update, default, typelib)
MYSQL_SYSVAR_SET(name, varname, opt, comment, check, update,
               default, typelib)
</pre></li></ul>
</div>
</li></ul>
</div>
<p>
            Internally, all mutable and plugin system variables are
            stored in a <code class="literal">HASH</code> structure.
          </p><p>
            Display of the server command-line help text is handled by
            compiling a <code class="literal">DYNAMIC_ARRAY</code> of all
            variables relevant to command-line options, sorting them,
            and then iterating through them to display each option.
          </p><p>
            When a command-line option has been handled, it is then
            removed from the <code class="literal">argv</code> by the
            <code class="literal">handle_option()</code> function
            (<code class="filename">my_getopt.c</code>); in effect, it is
            consumed.
          </p><p>
            The server processes command-line options during the plugin
            installation process, immediately after the plugin has been
            successfully loaded but before the plugin initialization
            function has been called
          </p><p>
            Plugins loaded at runtime do not benefit from any
            configuration options and must have usable defaults. Once
            they are installed, they are loaded at
            <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> initialization time and
            configuration options can be set at the command line or
            within <code class="filename">my.cnf</code>.
          </p><p>
            Plugins should consider the <code class="literal">thd</code> parameter
            to be read only.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="client-plugin-descriptors"></a>28.2.4.2.3 Client Plugin Descriptors</h5>

</div>

</div>

</div>
<p>
            Each client plugin must have a descriptor that provides
            information to the client plugin API. The descriptor
            structure begins with a fixed set of members common to all
            client plugins, followed by any members specific to the
            plugin type.
          </p><p>
            The <code class="literal">st_mysql_client_plugin</code> structure in
            the <code class="filename">client_plugin.h</code> file defines a
            <span class="quote">“<span class="quote">generic</span>”</span> descriptor that contains the common
            members:
          </p><pre class="programlisting">
struct st_mysql_client_plugin
{
  int type;
  unsigned int interface_version;
  const char *name;
  const char *author;
  const char *desc;
  unsigned int version[3];
  const char *license;
  void *mysql_api;
  int (*init)(char *, size_t, int, va_list);
  int (*deinit)();
  int (*options)(const char *option, const void *);
};
</pre><p>
            The common <code class="literal">st_mysql_client_plugin</code>
            descriptor structure members are used as follows.
            <code class="literal">char *</code> members should be specified as
            null-terminated strings.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                <code class="literal">type</code>: The plugin type. This must be
                one of the plugin-type values from
                <code class="filename">client_plugin.h</code>, such as
                <code class="literal">MYSQL_CLIENT_AUTHENTICATION_PLUGIN</code>.
              </p></li><li class="listitem"><p>
                <code class="literal">interface_version</code>: The plugin
                interface version. For example, this is
                <code class="literal">MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION</code>
                for an authentication plugin.
              </p></li><li class="listitem"><p>
                <code class="literal">name</code>: A string that gives the plugin
                name. This is the name by which you refer to the plugin
                when you call
                <a class="link" href="connectors-apis.html#mysql-options" title="27.7.7.50 mysql_options()"><code class="literal">mysql_options()</code></a> with the
                <code class="literal">MYSQL_DEFAULT_AUTH</code> option or specify
                the <code class="option">--default-auth</code> option to a MySQL
                client program.
              </p></li><li class="listitem"><p>
                <code class="literal">author</code>: A string naming the plugin
                author. This can be whatever you like.
              </p></li><li class="listitem"><p>
                <code class="literal">desc</code>: A string that provides a
                general description of the plugin. This can be whatever
                you like.
              </p></li><li class="listitem"><p>
                <code class="literal">version</code>: The plugin version as an
                array of three integers indicating the major, minor, and
                teeny versions. For example, <code class="literal">{1,2,3}</code>
                indicates version 1.2.3.
              </p></li><li class="listitem"><p>
                <code class="literal">license</code>: A string that specifies the
                license type.
              </p></li><li class="listitem"><p>
                <code class="literal">mysql_api</code>: For internal use. Specify
                it as <code class="literal">NULL</code> in the plugin descriptor.
              </p></li><li class="listitem"><p>
                <code class="literal">init</code>: A once-only initialization
                function, or <code class="literal">NULL</code> if there is no such
                function. The client library executes this function when
                it loads the plugin. The function returns zero for
                success and nonzero for failure.
              </p><p>
                The <code class="literal">init</code> function uses its first two
                arguments to return an error message if an error occurs.
                The first argument is a pointer to a
                <code class="literal">char</code> buffer, and the second argument
                indicates the buffer length. Any message returned by the
                <code class="literal">init</code> function must be
                null-terminated, so the maximum message length is the
                buffer length minus one. The next arguments are passed
                to <a class="link" href="connectors-apis.html#mysql-load-plugin" title="27.7.13.3 mysql_load_plugin()"><code class="literal">mysql_load_plugin()</code></a>.
                The first indicates how many more arguments there are (0
                if none), followed by any remaining arguments.
              </p></li><li class="listitem"><p>
                <code class="literal">deinit</code>: A once-only deinitialization
                function, or <code class="literal">NULL</code> if there is no such
                function. The client library executes this function when
                it unloads the plugin. The function takes no arguments.
                It returns zero for success and nonzero for failure.
              </p></li><li class="listitem"><p>
                <code class="literal">options</code>: A function for handling
                options passed to the plugin, or <code class="literal">NULL</code>
                if there is no such function. The function takes two
                arguments representing the option name and a pointer to
                its value. The function returns zero for success and
                nonzero for failure.
</p></li></ul>
</div>
<p>
            For a given client plugin type, the common descriptor
            members may be followed by additional members necessary to
            implement plugins of that type. For example, the
            <code class="literal">st_mysql_client_plugin_AUTHENTICATION</code>
            structure for authentication plugins has a function at the
            end that the client library calls to perform authentication.
          </p><p>
            To declare a plugin, use the
            <code class="literal">mysql_declare_client_plugin()</code> and
            <code class="literal">mysql_end_client_plugin</code> macros:
          </p><pre class="programlisting">
mysql_declare_client_plugin(<em class="replaceable"><code>plugin_type</code></em>)
   ... <em class="replaceable"><code>members common to all client plugins</code></em> ...
   ... <em class="replaceable"><code>type-specific extra members</code></em> ...
mysql_end_client_plugin;
</pre><p>
            Do not specify the <code class="literal">type</code> or
            <code class="literal">interface_version</code> member explicitly. The
            <code class="literal">mysql_declare_client_plugin()</code> macro uses
            the <em class="replaceable"><code>plugin_type</code></em> argument to
            generate their values automatically. For example, declare an
            authentication client plugin like this:
          </p><pre class="programlisting">
mysql_declare_client_plugin(AUTHENTICATION)
  "my_auth_plugin",
  "Author Name",
  "My Client Authentication Plugin",
  {1,0,0},
  "GPL",
  NULL,
  my_auth_init,
  my_auth_deinit,
  my_auth_options,
  my_auth_main
mysql_end_client_plugin;
</pre><p>
            This declaration uses the <code class="literal">AUTHENTICATION</code>
            argument to set the <code class="literal">type</code> and
            <code class="literal">interface_version</code> members to
            <code class="literal">MYSQL_CLIENT_AUTHENTICATION_PLUGIN</code> and
            <code class="literal">MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION</code>.
          </p><p>
            Depending on the plugin type, the descriptor may have other
            members following the common members. For example, for an
            authentication plugin, there is a function
            (<code class="literal">my_auth_main()</code> in the descriptor just
            shown) that handles communication with the server. See
            <a class="xref" href="extending-mysql.html#writing-authentication-plugins" title="28.2.4.9 Writing Authentication Plugins">Section 28.2.4.9, “Writing Authentication Plugins”</a>.
          </p><p>
            Normally, a client program that supports the use of
            authentication plugins causes a plugin to be loaded by
            calling <a class="link" href="connectors-apis.html#mysql-options" title="27.7.7.50 mysql_options()"><code class="literal">mysql_options()</code></a> to
            set the <code class="literal">MYSQL_DEFAULT_AUTH</code> and
            <code class="literal">MYSQL_PLUGIN_DIR</code> options:
          </p><pre class="programlisting">
char *plugin_dir = "<em class="replaceable"><code>path_to_plugin_dir</code></em>";
char *default_auth = "<em class="replaceable"><code>plugin_name</code></em>";

/* ... process command-line options ... */

mysql_options(&amp;mysql, MYSQL_PLUGIN_DIR, plugin_dir);
mysql_options(&amp;mysql, MYSQL_DEFAULT_AUTH, default_auth);
</pre><p>
            Typically, the program will also accept
            <code class="option">--plugin-dir</code> and
            <code class="option">--default-auth</code> options that enable users to
            override the default values.
          </p><p>
            Should a client program require lower-level plugin
            management, the client library contains functions that take
            an <code class="literal">st_mysql_client_plugin</code> argument. See
            <a class="xref" href="connectors-apis.html#c-api-plugin-functions" title="27.7.13 C API Client Plugin Functions">Section 27.7.13, “C API Client Plugin Functions”</a>.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="compiling-plugin-libraries"></a>28.2.4.3 Compiling and Installing Plugin Libraries</h4>

</div>

</div>

</div>
<p>
          After your plugin is written, you must compile it and install
          it. The procedure for compiling shared objects varies from
          system to system. If you build your library using
          <code class="literal">CMake</code>, it should be able to generate the
          correct compilation commands for your system. If the library
          is named <code class="literal">somepluglib</code>, you should end up
          with a shared library file that has a name something like
          <code class="filename">somepluglib.so</code>. (The
          <code class="filename">.so</code> file name suffix might differ on your
          system.)
        </p><p>
          To use <code class="literal">CMake</code>, you'll need to set up the
          configuration files to enable the plugin to be compiled and
          installed. Use the plugin examples under the
          <code class="filename">plugin</code> directory of a MySQL source
          distribution as a guide.
        </p><p>
          Create <code class="filename">CMakeLists.txt</code>, which should look
          something like this:
        </p><pre class="programlisting">
MYSQL_ADD_PLUGIN(somepluglib somepluglib.c
  MODULE_ONLY MODULE_OUTPUT_NAME "somepluglib")
</pre><p>
          When <code class="literal">CMake</code> generates the
          <code class="filename">Makefile</code>, it should take care of passing
          to the compilation command the
          <code class="literal">-DMYSQL_DYNAMIC_PLUGIN</code> flag, and passing to
          the linker the <code class="literal">-lmysqlservices</code> flag, which
          is needed to link in any functions from services provided
          through the plugin services interface. See
          <a class="xref" href="extending-mysql.html#component-plugin-services" title="28.3 MySQL Services for Components and Plugins">Section 28.3, “MySQL Services for Components and Plugins”</a>.
        </p><p>
          Run <span class="command"><strong>CMake</strong></span>, then run
          <span class="command"><strong>make</strong></span>:
        </p><pre class="programlisting">
shell&gt; <strong class="userinput"><code>cmake .</code></strong>
shell&gt; <strong class="userinput"><code>make</code></strong>
</pre><p>
          If you need to specify configuration options to
          <span class="command"><strong>CMake</strong></span>, see
          <a class="xref" href="installing.html#source-configuration-options" title="2.9.4 MySQL Source-Configuration Options">Section 2.9.4, “MySQL Source-Configuration Options”</a>, for a list.
          For example, you might want to specify
          <a class="link" href="installing.html#option_cmake_cmake_install_prefix"><code class="option">CMAKE_INSTALL_PREFIX</code></a> to indicate
          the MySQL base directory under which the plugin should be
          installed. You can see what value to use for this option with
          <a class="link" href="sql-syntax.html#show-variables" title="13.7.6.39 SHOW VARIABLES Syntax"><code class="literal">SHOW VARIABLES</code></a>:
        </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>SHOW VARIABLES LIKE 'basedir';</code></strong>
+---------------+------------------+
| Variable_name | Value            |
+---------------+------------------+
| base          | /usr/local/mysql |
+---------------+------------------+
</pre><p>
          The location of the plugin directory where you should install
          the library is given by the
          <a class="link" href="server-administration.html#sysvar_plugin_dir"><code class="literal">plugin_dir</code></a> system variable.
          For example:
        </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>SHOW VARIABLES LIKE 'plugin_dir';</code></strong>
+---------------+-----------------------------------+
| Variable_name | Value                             |
+---------------+-----------------------------------+
| plugin_dir    | /usr/local/mysql/lib/mysql/plugin |
+---------------+-----------------------------------+
</pre><p>
          To install the plugin library, use <span class="command"><strong>make</strong></span>:
        </p><pre class="programlisting">
shell&gt; <strong class="userinput"><code>make install</code></strong>
</pre><p>
          Verify that <span class="command"><strong>make install</strong></span> installed the
          plugin library in the proper directory. After installing it,
          make sure that the library permissions permit it to be
          executed by the server.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="writing-full-text-plugins"></a>28.2.4.4 Writing Full-Text Parser Plugins</h4>

</div>

</div>

</div>
<p>
          MySQL supports server-side full-text parser plugins with
          <a class="link" href="storage-engines.html#myisam-storage-engine" title="16.2 The MyISAM Storage Engine"><code class="literal">MyISAM</code></a> and
          <a class="link" href="innodb-storage-engine.html" title="Chapter 15 The InnoDB Storage Engine"><code class="literal">InnoDB</code></a>. For introductory
          information about full-text parser plugins, see
          <a class="xref" href="extending-mysql.html#full-text-plugin-type" title="Full-Text Parser Plugins">Full-Text Parser Plugins</a>.
        </p><p>
          A full-text parser plugin can be used to replace or modify the
          built-in full-text parser. This section describes how to write
          a full-text parser plugin named
          <code class="literal">simple_parser</code>. This plugin performs parsing
          based on simpler rules than those used by the MySQL built-in
          full-text parser: Words are nonempty runs of whitespace
          characters.
        </p><p>
          The instructions use the source code in the
          <code class="filename">plugin/fulltext</code> directory of MySQL source
          distributions, so change location into that directory. The
          following procedure describes how the plugin library is
          created:
</p>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
              To write a full-text parser plugin, include the following
              header file in the plugin source file. Other MySQL or
              general header files might also be needed, depending on
              the plugin capabilities and requirements.
            </p><pre class="programlisting">
#include &lt;mysql/plugin.h&gt;
</pre><p>
              <code class="filename">plugin.h</code> defines the
              <code class="literal">MYSQL_FTPARSER_PLUGIN</code> server plugin
              type and the data structures needed to declare the plugin.
            </p></li><li class="listitem"><p>
              Set up the library descriptor for the plugin library file.
            </p><p>
              This descriptor contains the general plugin descriptor for
              the server plugin. For a full-text parser plugin, the type
              must be <code class="literal">MYSQL_FTPARSER_PLUGIN</code>. This is
              the value that identifies the plugin as being legal for
              use in a <code class="literal">WITH PARSER</code> clause when
              creating a <code class="literal">FULLTEXT</code> index. (No other
              plugin type is legal for this clause.)
            </p><p>
              For example, the library descriptor for a library that
              contains a single full-text parser plugin named
              <code class="literal">simple_parser</code> looks like this:
            </p><pre class="programlisting">
mysql_declare_plugin(ftexample)
{
  MYSQL_FTPARSER_PLUGIN,      /* type                            */
  &amp;simple_parser_descriptor,  /* descriptor                      */
  "simple_parser",            /* name                            */
  "Oracle Corporation",       /* author                          */
  "Simple Full-Text Parser",  /* description                     */
  PLUGIN_LICENSE_GPL,         /* plugin license                  */
  simple_parser_plugin_init,  /* init function (when loaded)     */
  simple_parser_plugin_deinit,/* deinit function (when unloaded) */
  0x0001,                     /* version                         */
  simple_status,              /* status variables                */
  simple_system_variables,    /* system variables                */
  NULL,
  0
}
mysql_declare_plugin_end;
</pre><p>
              The <code class="literal">name</code> member
              (<code class="literal">simple_parser</code>) indicates the name to
              use for references to the plugin in statements such as
              <a class="link" href="sql-syntax.html#install-plugin" title="13.7.4.4 INSTALL PLUGIN Syntax"><code class="literal">INSTALL PLUGIN</code></a> or
              <a class="link" href="sql-syntax.html#uninstall-plugin" title="13.7.4.6 UNINSTALL PLUGIN Syntax"><code class="literal">UNINSTALL PLUGIN</code></a>. This is
              also the name displayed by <a class="link" href="sql-syntax.html#show-plugins" title="13.7.6.25 SHOW PLUGINS Syntax"><code class="literal">SHOW
              PLUGINS</code></a> or
              <a class="link" href="information-schema.html#plugins-table" title="24.15 The INFORMATION_SCHEMA PLUGINS Table"><code class="literal">INFORMATION_SCHEMA.PLUGINS</code></a>.
            </p><p>
              For more information, see
              <a class="xref" href="extending-mysql.html#server-plugin-descriptors" title="28.2.4.2.1 Server Plugin Library and Plugin Descriptors">Section 28.2.4.2.1, “Server Plugin Library and Plugin Descriptors”</a>.
            </p></li><li class="listitem"><p>
              Set up the type-specific plugin descriptor.
            </p><p>
              Each general plugin descriptor in the library descriptor
              points to a type-specific descriptor. For a full-text
              parser plugin, the type-specific descriptor is an instance
              of the <code class="literal">st_mysql_ftparser</code> structure in
              the <code class="filename">plugin.h</code> file:
            </p><pre class="programlisting">
struct st_mysql_ftparser
{
  int interface_version;
  int (*parse)(MYSQL_FTPARSER_PARAM *param);
  int (*init)(MYSQL_FTPARSER_PARAM *param);
  int (*deinit)(MYSQL_FTPARSER_PARAM *param);
};
</pre><p>
              As shown by the structure definition, the descriptor has
              an interface version number and contains pointers to three
              functions.
            </p><p>
              The interface version number is specified using a symbol,
              which is in the form:
              <code class="literal">MYSQL_<em class="replaceable"><code>xxx</code></em>_INTERFACE_VERSION</code>.
              For full-text parser plugins, the symbol is
              <code class="literal">MYSQL_FTPARSER_INTERFACE_VERSION</code>. In
              the source code, you will find the actual interface
              version number for the full-text parser plugin defined in
              <code class="filename">include/mysql/plugin_ftparser.h</code>. The
              current interface version number is
              <code class="literal">0x0101</code>.
            </p><p>
              The <code class="literal">init</code> and <code class="literal">deinit</code>
              members should point to a function or be set to 0 if the
              function is not needed. The <code class="literal">parse</code>
              member must point to the function that performs the
              parsing.
            </p><p>
              In the <code class="literal">simple_parser</code> declaration, that
              descriptor is indicated by
              <code class="literal">&amp;simple_parser_descriptor</code>. The
              descriptor specifies the version number for the full-text
              plugin interface (as given by
              <code class="literal">MYSQL_FTPARSER_INTERFACE_VERSION</code>), and
              the plugin's parsing, initialization, and deinitialization
              functions:
            </p><pre class="programlisting">
static struct st_mysql_ftparser simple_parser_descriptor=
{
  MYSQL_FTPARSER_INTERFACE_VERSION, /* interface version      */
  simple_parser_parse,              /* parsing function       */
  simple_parser_init,               /* parser init function   */
  simple_parser_deinit              /* parser deinit function */
};
</pre><p>
              A full-text parser plugin is used in two different
              contexts, indexing and searching. In both contexts, the
              server calls the initialization and deinitialization
              functions at the beginning and end of processing each SQL
              statement that causes the plugin to be invoked. However,
              during statement processing, the server calls the main
              parsing function in context-specific fashion:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                  For indexing, the server calls the parser for each
                  column value to be indexed.
                </p></li><li class="listitem"><p>
                  For searching, the server calls the parser to parse
                  the search string. The parser might also be called for
                  rows processed by the statement. In natural language
                  mode, there is no need for the server to call the
                  parser. For boolean mode phrase searches or natural
                  language searches with query expansion, the parser is
                  used to parse column values for information that is
                  not in the index. Also, if a boolean mode search is
                  done for a column that has no
                  <code class="literal">FULLTEXT</code> index, the built-in parser
                  will be called. (Plugins are associated with specific
                  indexes. If there is no index, no plugin is used.)
</p></li></ul>
</div>
<p>
              The plugin declaration in the general plugin descriptor
              has <code class="literal">init</code> and <code class="literal">deinit</code>
              members that point initialization and deinitialization
              functions, and so does the type-specific plugin descriptor
              to which it points. However, these pairs of functions have
              different purposes and are invoked for different reasons:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                  For the plugin declaration in the general plugin
                  descriptor, the initialization and deinitialization
                  functions are invoked when the plugin is loaded and
                  unloaded.
                </p></li><li class="listitem"><p>
                  For the type-specific plugin descriptor, the
                  initialization and deinitialization functions are
                  invoked per SQL statement for which the plugin is
                  used.
</p></li></ul>
</div>
<p>
              Each interface function named in the plugin descriptor
              should return zero for success or nonzero for failure, and
              each of them receives an argument that points to a
              <code class="literal">MYSQL_FTPARSER_PARAM</code> structure
              containing the parsing context. The structure has this
              definition:
            </p><pre class="programlisting">
typedef struct st_mysql_ftparser_param
{
  int (*mysql_parse)(struct st_mysql_ftparser_param *,
                     char *doc, int doc_len);
  int (*mysql_add_word)(struct st_mysql_ftparser_param *,
                        char *word, int word_len,
                        MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
  void *ftparser_state;
  void *mysql_ftparam;
  struct charset_info_st *cs;
  char *doc;
  int length;
  int flags;
  enum enum_ftparser_mode mode;
} MYSQL_FTPARSER_PARAM;
</pre><p>
              The structure members are used as follows:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                  <code class="literal">mysql_parse</code>: A pointer to a
                  callback function that invokes the server's built-in
                  parser. Use this callback when the plugin acts as a
                  front end to the built-in parser. That is, when the
                  plugin parsing function is called, it should process
                  the input to extract the text and pass the text to the
                  <code class="literal">mysql_parse</code> callback.
                </p><p>
                  The first parameter for this callback function should
                  be the <code class="literal">param</code> value itself:
                </p><pre class="programlisting">
param-&gt;mysql_parse(param, ...);
</pre><p>
                  A front end plugin can extract text and pass it all at
                  once to the built-in parser, or it can extract and
                  pass text to the built-in parser a piece at a time.
                  However, in this case, the built-in parser treats the
                  pieces of text as though there are implicit word
                  breaks between them.
                </p></li><li class="listitem"><p>
                  <code class="literal">mysql_add_word</code>: A pointer to a
                  callback function that adds a word to a full-text
                  index or to the list of search terms. Use this
                  callback when the parser plugin replaces the built-in
                  parser. That is, when the plugin parsing function is
                  called, it should parse the input into words and
                  invoke the <code class="literal">mysql_add_word</code> callback
                  for each word.
                </p><p>
                  The first parameter for this callback function should
                  be the <code class="literal">param</code> value itself:
                </p><pre class="programlisting">
param-&gt;mysql_add_word(param, ...);
</pre></li><li class="listitem"><p>
                  <code class="literal">ftparser_state</code>: This is a generic
                  pointer. The plugin can set it to point to information
                  to be used internally for its own purposes.
                </p></li><li class="listitem"><p>
                  <code class="literal">mysql_ftparam</code>: This is set by the
                  server. It is passed as the first argument to the
                  <code class="literal">mysql_parse</code> or
                  <code class="literal">mysql_add_word</code> callback.
                </p></li><li class="listitem"><p>
                  <code class="literal">cs</code>: A pointer to information about
                  the character set of the text, or 0 if no information
                  is available.
                </p></li><li class="listitem"><p>
                  <code class="literal">doc</code>: A pointer to the text to be
                  parsed.
                </p></li><li class="listitem"><p>
                  <code class="literal">length</code>: The length of the text to
                  be parsed, in bytes.
                </p></li><li class="listitem"><p>
                  <code class="literal">flags</code>: Parser flags. This is zero
                  if there are no special flags. The only nonzero flag
                  is <code class="literal">MYSQL_FTFLAGS_NEED_COPY</code>, which
                  means that <code class="literal">mysql_add_word()</code> must
                  save a copy of the word (that is, it cannot use a
                  pointer to the word because the word is in a buffer
                  that will be overwritten.)
                </p><p>
                  This flag might be set or reset by MySQL before
                  calling the parser plugin, by the parser plugin
                  itself, or by the <code class="literal">mysql_parse()</code>
                  function.
                </p></li><li class="listitem"><p>
                  <code class="literal">mode</code>: The parsing mode. This value
                  will be one of the following constants:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                      <code class="literal">MYSQL_FTPARSER_SIMPLE_MODE</code>:
                      Parse in fast and simple mode, which is used for
                      indexing and for natural language queries. The
                      parser should pass to the server only those words
                      that should be indexed. If the parser uses length
                      limits or a stopword list to determine which words
                      to ignore, it should not pass such words to the
                      server.
                    </p></li><li class="listitem"><p>
                      <code class="literal">MYSQL_FTPARSER_WITH_STOPWORDS</code>:
                      Parse in stopword mode. This is used in boolean
                      searches for phrase matching. The parser should
                      pass all words to the server, even stopwords or
                      words that are outside any normal length limits.
                    </p></li><li class="listitem"><p>
                      <code class="literal">MYSQL_FTPARSER_FULL_BOOLEAN_INFO</code>:
                      Parse in boolean mode. This is used for parsing
                      boolean query strings. The parser should recognize
                      not only words but also boolean-mode operators and
                      pass them to the server as tokens using the
                      <code class="literal">mysql_add_word</code> callback. To
                      tell the server what kind of token is being
                      passed, the plugin needs to fill in a
                      <code class="literal">MYSQL_FTPARSER_BOOLEAN_INFO</code>
                      structure and pass a pointer to it.
</p></li></ul>
</div>
</li></ul>
</div>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
<div class="admon-title">
Note
</div>
<p>
                For <code class="literal">MyISAM</code>, the stopword list and
                <a class="link" href="server-administration.html#sysvar_ft_min_word_len"><code class="literal">ft_min_word_len</code></a> and
                <a class="link" href="server-administration.html#sysvar_ft_max_word_len"><code class="literal">ft_max_word_len</code></a> are
                checked inside the tokenizer. For
                <code class="literal">InnoDB</code>, the stopword list and
                equivalent word length variable settings
                (<a class="link" href="innodb-storage-engine.html#sysvar_innodb_ft_min_token_size"><code class="literal">innodb_ft_min_token_size</code></a>
                and
                <a class="link" href="innodb-storage-engine.html#sysvar_innodb_ft_max_token_size"><code class="literal">innodb_ft_max_token_size</code></a>)
                are checked outside of the tokenizer. As a result,
                <code class="literal">InnoDB</code> plugin parsers do not need to
                check the stopword list,
                <a class="link" href="innodb-storage-engine.html#sysvar_innodb_ft_min_token_size"><code class="literal">innodb_ft_min_token_size</code></a>,
                or
                <a class="link" href="innodb-storage-engine.html#sysvar_innodb_ft_max_token_size"><code class="literal">innodb_ft_max_token_size</code></a>.
                Instead, it is recommended that all words be returned to
                <code class="literal">InnoDB</code>. However, if you want to check
                stopwords within your plugin parser, use
                <code class="literal">MYSQL_FTPARSER_SIMPLE_MODE</code>, which is
                for full-text search index and natural language search.
                For <code class="literal">MYSQL_FTPARSER_WITH_STOPWORDS</code> and
                <code class="literal">MYSQL_FTPARSER_FULL_BOOLEAN_INFO</code>
                modes, it is recommended that all words be returned to
                <code class="literal">InnoDB</code> including stopwords, in case
                of phrase searches.
</p>
</div>
<p>
              If the parser is called in boolean mode, the
              <code class="literal">param-&gt;mode</code> value will be
              <code class="literal">MYSQL_FTPARSER_FULL_BOOLEAN_INFO</code>. The
              <code class="literal">MYSQL_FTPARSER_BOOLEAN_INFO</code> structure
              that the parser uses for passing token information to the
              server looks like this:
            </p><pre class="programlisting">
typedef struct st_mysql_ftparser_boolean_info
{
  enum enum_ft_token_type type;
  int yesno;
  int weight_adjust;
  char wasign;
  char trunc;
  int position;
  /* These are parser state and must be removed. */
  char prev;
  char *quot;
} MYSQL_FTPARSER_BOOLEAN_INFO;
</pre><p>
              The parser should fill in the structure members as
              follows:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                  <code class="literal">type</code>: The token type. The following
                  table shows the permissible types.
</p>
<div class="table">
<a name="idm139899455833680"></a><p class="title"><b>Table 28.3 Full-Text Parser Token Types</b></p>
<div class="table-contents">
<table><col width="40%"><col width="60%"><thead><tr>
                      <th scope="col">Token Value</th>
                      <th scope="col">Meaning</th>
                    </tr></thead><tbody><tr>
                      <td scope="row"><code class="literal">FT_TOKEN_EOF</code></td>
                      <td>End of data</td>
                    </tr><tr>
                      <td scope="row"><code class="literal">FT_TOKEN_WORD</code></td>
                      <td>A regular word</td>
                    </tr><tr>
                      <td scope="row"><code class="literal">FT_TOKEN_LEFT_PAREN</code></td>
                      <td>The beginning of a group or subexpression</td>
                    </tr><tr>
                      <td scope="row"><code class="literal">FT_TOKEN_RIGHT_PAREN</code></td>
                      <td>The end of a group or subexpression</td>
                    </tr><tr>
                      <td scope="row"><code class="literal">FT_TOKEN_STOPWORD</code></td>
                      <td>A stopword</td>
</tr></tbody></table>
</div>

</div>
<br class="table-break"></li><li class="listitem"><p>
                  <code class="literal">yesno</code>: Whether the word must be
                  present for a match to occur. 0 means that the word is
                  optional but increases the match relevance if it is
                  present. Values larger than 0 mean that the word must
                  be present. Values smaller than 0 mean that the word
                  must not be present.
                </p></li><li class="listitem"><p>
                  <code class="literal">weight_adjust</code>: A weighting factor
                  that determines how much a match for the word counts.
                  It can be used to increase or decrease the word's
                  importance in relevance calculations. A value of zero
                  indicates no weight adjustment. Values greater than or
                  less than zero mean higher or lower weight,
                  respectively. The examples at
                  <a class="xref" href="functions.html#fulltext-boolean" title="12.9.2 Boolean Full-Text Searches">Section 12.9.2, “Boolean Full-Text Searches”</a>, that use the
                  <code class="literal">&lt;</code> and <code class="literal">&gt;</code>
                  operators illustrate how weighting works.
                </p></li><li class="listitem"><p>
                  <code class="literal">wasign</code>: The sign of the weighting
                  factor. A negative value acts like the
                  <code class="literal">~</code> boolean-search operator, which
                  causes the word's contribution to the relevance to be
                  negative.
                </p></li><li class="listitem"><p>
                  <code class="literal">trunc</code>: Whether matching should be
                  done as if the boolean-mode <code class="literal">*</code>
                  truncation operator had been given.
                </p></li><li class="listitem"><p>
                  <code class="literal">position</code>: Start position of the
                  word in the document, in bytes. Used by
                  <code class="literal">InnoDB</code> full-text search. For
                  existing plugins that are called in boolean mode,
                  support must be added for the position member.
</p></li></ul>
</div>
<p>
              Plugins should not use the <code class="literal">prev</code> and
              <code class="literal">quot</code> members of the
              <code class="literal">MYSQL_FTPARSER_BOOLEAN_INFO</code> structure.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
                The plugin parser framework does not support:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                    The <code class="literal">@distance</code> boolean operator.
                  </p></li><li class="listitem"><p>
                    A leading plus sign (<code class="literal">+</code>) or minus
                    sign (<code class="literal">-</code>) boolean operator
                    followed by a space and then a word (<code class="literal">'+
                    apple'</code> or <code class="literal">'- apple'</code>).
                    The leading plus or minus sign must be directly
                    adjacent to the word, for example:
                    <code class="literal">'+apple'</code> or
                    <code class="literal">'-apple'</code>.
</p></li></ul>
</div>
<p>
                For information about boolean full-text search
                operators, see <a class="xref" href="functions.html#fulltext-boolean" title="12.9.2 Boolean Full-Text Searches">Section 12.9.2, “Boolean Full-Text Searches”</a>.
</p>
</div>
</li><li class="listitem"><p>
              Set up the plugin interface functions.
            </p><p>
              The general plugin descriptor in the library descriptor
              names the initialization and deinitialization functions
              that the server should invoke when it loads and unloads
              the plugin. For <code class="literal">simple_parser</code>, these
              functions do nothing but return zero to indicate that they
              succeeded:
            </p><pre class="programlisting">
static int simple_parser_plugin_init(void *arg __attribute__((unused)))
{
  return(0);
}

static int simple_parser_plugin_deinit(void *arg __attribute__((unused)))
{
  return(0);
}
</pre><p>
              Because those functions do not actually do anything, you
              could omit them and specify 0 for each of them in the
              plugin declaration.
            </p><p>
              The type-specific plugin descriptor for
              <code class="literal">simple_parser</code> names the initialization,
              deinitialization, and parsing functions that the server
              invokes when the plugin is used. For
              <code class="literal">simple_parser</code>, the initialization and
              deinitialization functions do nothing:
            </p><pre class="programlisting">
static int simple_parser_init(MYSQL_FTPARSER_PARAM *param
                              __attribute__((unused)))
{
  return(0);
}

static int simple_parser_deinit(MYSQL_FTPARSER_PARAM *param
                                __attribute__((unused)))
{
  return(0);
}
</pre><p>
              Here too, because those functions do nothing, you could
              omit them and specify 0 for each of them in the plugin
              descriptor.
            </p><p>
              The main parsing function,
              <code class="literal">simple_parser_parse()</code>, acts as a
              replacement for the built-in full-text parser, so it needs
              to split text into words and pass each word to the server.
              The parsing function's first argument is a pointer to a
              structure that contains the parsing context. This
              structure has a <code class="literal">doc</code> member that points
              to the text to be parsed, and a <code class="literal">length</code>
              member that indicates how long the text is. The simple
              parsing done by the plugin considers nonempty runs of
              whitespace characters to be words, so it identifies words
              like this:
            </p><pre class="programlisting">
static int simple_parser_parse(MYSQL_FTPARSER_PARAM *param)
{
  char *end, *start, *docend= param-&gt;doc + param-&gt;length;

  for (end= start= param-&gt;doc;; end++)
  {
    if (end == docend)
    {
      if (end &gt; start)
        add_word(param, start, end - start);
      break;
    }
    else if (isspace(*end))
    {
      if (end &gt; start)
        add_word(param, start, end - start);
      start= end + 1;
    }
  }
  return(0);
}
</pre><p>
              As the parser finds each word, it invokes a function
              <code class="literal">add_word()</code> to pass the word to the
              server. <code class="literal">add_word()</code> is a helper function
              only; it is not part of the plugin interface. The parser
              passes the parsing context pointer to
              <code class="literal">add_word()</code>, as well as a pointer to the
              word and a length value:
            </p><pre class="programlisting">
static void add_word(MYSQL_FTPARSER_PARAM *param, char *word, size_t len)
{
  MYSQL_FTPARSER_BOOLEAN_INFO bool_info=
    { FT_TOKEN_WORD, 0, 0, 0, 0, 0, ' ', 0 };

  param-&gt;mysql_add_word(param, word, len, &amp;bool_info);
}
</pre><p>
              For boolean-mode parsing, <code class="literal">add_word()</code>
              fills in the members of the <code class="literal">bool_info</code>
              structure as described earlier in the discussion of the
              <code class="literal">st_mysql_ftparser_boolean_info</code>
              structure.
            </p></li><li class="listitem"><p>
              Set up the status variables. For the
              <code class="literal">simple_parser</code> plugin, the following
              status variable array sets up one status variable with a
              value that is static text, and another with a value that
              is stored in a long integer variable:
            </p><pre class="programlisting">
long number_of_calls= 0;

struct st_mysql_show_var simple_status[]=
{
  {"simple_parser_static", (char *)"just a static text", SHOW_CHAR},
  {"simple_parser_called", (char *)&amp;number_of_calls,     SHOW_LONG},
  {0,0,0}
};
</pre><p>
              By using status variable names that begin with the plugin
              name, you can easily display the variables for a plugin
              with <a class="link" href="sql-syntax.html#show-status" title="13.7.6.35 SHOW STATUS Syntax"><code class="literal">SHOW STATUS</code></a>:
            </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>SHOW STATUS LIKE 'simple_parser%';</code></strong>
+----------------------+--------------------+
| Variable_name        | Value              |
+----------------------+--------------------+
| simple_parser_static | just a static text |
| simple_parser_called | 0                  |
+----------------------+--------------------+
</pre></li><li class="listitem"><p>
              To compile and install a plugin library file, use the
              instructions in
              <a class="xref" href="extending-mysql.html#compiling-plugin-libraries" title="28.2.4.3 Compiling and Installing Plugin Libraries">Section 28.2.4.3, “Compiling and Installing Plugin Libraries”</a>. To make the
              library file available for use, install it in the plugin
              directory (the directory named by the
              <a class="link" href="server-administration.html#sysvar_plugin_dir"><code class="literal">plugin_dir</code></a> system
              variable). For the <code class="literal">simple_parser</code>
              plugin, it is compiled and installed when you build MySQL
              from source. It is also included in binary distributions.
              The build process produces a shared object library with a
              name of <code class="filename">mypluglib.so</code> (the
              <code class="filename">.so</code> suffix might differ depending on
              your platform).
            </p></li><li class="listitem"><p>
              To use the plugin, register it with the server. For
              example, to register the plugin at runtime, use this
              statement (adjust the <code class="filename">.so</code> suffix for
              your platform as necessary):
            </p><pre class="programlisting">
INSTALL PLUGIN simple_parser SONAME 'mypluglib.so';
</pre><p>
              For additional information about plugin loading, see
              <a class="xref" href="server-administration.html#server-plugin-loading" title="5.6.1 Installing and Uninstalling Plugins">Section 5.6.1, “Installing and Uninstalling Plugins”</a>.
            </p></li><li class="listitem"><p>
              To verify plugin installation, examine the
              <a class="link" href="information-schema.html#plugins-table" title="24.15 The INFORMATION_SCHEMA PLUGINS Table"><code class="literal">INFORMATION_SCHEMA.PLUGINS</code></a>
              table or use the <a class="link" href="sql-syntax.html#show-plugins" title="13.7.6.25 SHOW PLUGINS Syntax"><code class="literal">SHOW
              PLUGINS</code></a> statement. See
              <a class="xref" href="server-administration.html#obtaining-plugin-information" title="5.6.2 Obtaining Server Plugin Information">Section 5.6.2, “Obtaining Server Plugin Information”</a>.
            </p></li><li class="listitem"><p>
              Test the plugin to verify that it works properly.
            </p><p>
              Create a table that contains a string column and associate
              the parser plugin with a <code class="literal">FULLTEXT</code> index
              on the column:
            </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>CREATE TABLE t (c VARCHAR(255),</code></strong>
    -&gt; <strong class="userinput"><code>  FULLTEXT (c) WITH PARSER simple_parser</code></strong>
    -&gt; <strong class="userinput"><code>) ENGINE=MyISAM;</code></strong>
Query OK, 0 rows affected (0.01 sec)
</pre><p>
              Insert some text into the table and try some searches.
              These should verify that the parser plugin treats all
              nonwhitespace characters as word characters:
            </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>INSERT INTO t VALUES</code></strong>
    -&gt; <strong class="userinput"><code>  ('utf8mb4_0900_as_cs is a case-sensitive collation'),</code></strong>
    -&gt; <strong class="userinput"><code>  ('I\'d like a case of oranges'),</code></strong>
    -&gt; <strong class="userinput"><code>  ('this is sensitive information'),</code></strong>
    -&gt; <strong class="userinput"><code>  ('another row'),</code></strong>
    -&gt; <strong class="userinput"><code>  ('yet another row');</code></strong>
Query OK, 5 rows affected (0.02 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql&gt; <strong class="userinput"><code>SELECT c FROM t;</code></strong>
+--------------------------------------------------+
| c                                                |
+--------------------------------------------------+
| utf8mb4_0900_as_cs is a case-sensitive collation |
| I'd like a case of oranges                       |
| this is sensitive information                    |
| another row                                      |
| yet another row                                  |
+--------------------------------------------------+
5 rows in set (0.00 sec)

mysql&gt; <strong class="userinput"><code>SELECT MATCH(c) AGAINST('case') FROM t;</code></strong>
+--------------------------+
| MATCH(c) AGAINST('case') |
+--------------------------+
|                        0 |
|          1.2968142032623 |
|                        0 |
|                        0 |
|                        0 |
+--------------------------+
5 rows in set (0.00 sec)

mysql&gt; <strong class="userinput"><code>SELECT MATCH(c) AGAINST('sensitive') FROM t;</code></strong>
+-------------------------------+
| MATCH(c) AGAINST('sensitive') |
+-------------------------------+
|                             0 |
|                             0 |
|               1.3253291845322 |
|                             0 |
|                             0 |
+-------------------------------+
5 rows in set (0.01 sec)

mysql&gt; <strong class="userinput"><code>SELECT MATCH(c) AGAINST('case-sensitive') FROM t;</code></strong>
+------------------------------------+
| MATCH(c) AGAINST('case-sensitive') |
+------------------------------------+
|                    1.3109166622162 |
|                                  0 |
|                                  0 |
|                                  0 |
|                                  0 |
+------------------------------------+
5 rows in set (0.01 sec)

mysql&gt; <strong class="userinput"><code>SELECT MATCH(c) AGAINST('I\'d') FROM t;</code></strong>
+--------------------------+
| MATCH(c) AGAINST('I\'d') |
+--------------------------+
|                        0 |
|          1.2968142032623 |
|                        0 |
|                        0 |
|                        0 |
+--------------------------+
5 rows in set (0.01 sec)
</pre><p>
              Neither <span class="quote">“<span class="quote">case</span>”</span> nor <span class="quote">“<span class="quote">insensitive</span>”</span>
              match <span class="quote">“<span class="quote">case-insensitive</span>”</span> the way that they
              would for the built-in parser.
</p></li></ol>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="writing-daemon-plugins"></a>28.2.4.5 Writing Daemon Plugins</h4>

</div>

</div>

</div>
<p>
          A daemon plugin is a simple type of plugin used for code that
          should be run by the server but that does not communicate with
          it. This section describes how to write a daemon server
          plugin, using the example plugin found in the
          <code class="literal">plugin/daemon_example</code> directory of MySQL
          source distributions. That directory contains the
          <code class="literal">daemon_example.cc</code> source file for a daemon
          plugin named <code class="literal">daemon_example</code> that writes a
          heartbeat string at regular intervals to a file named
          <code class="filename">mysql-heartbeat.log</code> in the data
          directory.
        </p><p>
          To write a daemon plugin, include the following header file in
          the plugin source file. Other MySQL or general header files
          might also be needed, depending on the plugin capabilities and
          requirements.
        </p><pre class="programlisting">
#include &lt;mysql/plugin.h&gt;
</pre><p>
          <code class="filename">plugin.h</code> defines the
          <code class="literal">MYSQL_DAEMON_PLUGIN</code> server plugin type and
          the data structures needed to declare the plugin.
        </p><p>
          The <code class="filename">daemon_example.cc</code> file sets up the
          library descriptor as follows. The library descriptor includes
          a single general server plugin descriptor.
        </p><pre class="programlisting">
mysql_declare_plugin(daemon_example)
{
  MYSQL_DAEMON_PLUGIN,
  &amp;daemon_example_plugin,
  "daemon_example",
  "Brian Aker",
  "Daemon example, creates a heartbeat beat file in mysql-heartbeat.log",
  PLUGIN_LICENSE_GPL,
  daemon_example_plugin_init, /* Plugin Init */
  daemon_example_plugin_deinit, /* Plugin Deinit */
  0x0100 /* 1.0 */,
  NULL,                       /* status variables                */
  NULL,                       /* system variables                */
  NULL,                       /* config options                  */
  0,                          /* flags                           */
}
mysql_declare_plugin_end;
</pre><p>
          The <code class="literal">name</code> member
          (<code class="literal">daemon_example</code>) indicates the name to use
          for references to the plugin in statements such as
          <a class="link" href="sql-syntax.html#install-plugin" title="13.7.4.4 INSTALL PLUGIN Syntax"><code class="literal">INSTALL PLUGIN</code></a> or
          <a class="link" href="sql-syntax.html#uninstall-plugin" title="13.7.4.6 UNINSTALL PLUGIN Syntax"><code class="literal">UNINSTALL PLUGIN</code></a>. This is also
          the name displayed by <a class="link" href="sql-syntax.html#show-plugins" title="13.7.6.25 SHOW PLUGINS Syntax"><code class="literal">SHOW
          PLUGINS</code></a> or
          <a class="link" href="information-schema.html#plugins-table" title="24.15 The INFORMATION_SCHEMA PLUGINS Table"><code class="literal">INFORMATION_SCHEMA.PLUGINS</code></a>.
        </p><p>
          The second member of the plugin descriptor,
          <code class="literal">daemon_example_plugin</code>, points to the
          type-specific daemon plugin descriptor. This structure
          consists only of the type-specific API version number:
        </p><pre class="programlisting">
struct st_mysql_daemon daemon_example_plugin=
{ MYSQL_DAEMON_INTERFACE_VERSION  };
</pre><p>
          The type-specific structure has no interface functions. There
          is no communication between the server and the plugin, except
          that the server calls the initialization and deinitialization
          functions from the general plugin descriptor to start and stop
          the plugin:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              <code class="literal">daemon_example_plugin_init()</code> opens the
              heartbeat file and spawns a thread that wakes up
              periodically and writes the next message to the file.
            </p></li><li class="listitem"><p>
              <code class="literal">daemon_example_plugin_deinit()</code> closes
              the file and performs other cleanup.
</p></li></ul>
</div>
<p>
          To compile and install a plugin library file, use the
          instructions in <a class="xref" href="extending-mysql.html#compiling-plugin-libraries" title="28.2.4.3 Compiling and Installing Plugin Libraries">Section 28.2.4.3, “Compiling and Installing Plugin Libraries”</a>.
          To make the library file available for use, install it in the
          plugin directory (the directory named by the
          <a class="link" href="server-administration.html#sysvar_plugin_dir"><code class="literal">plugin_dir</code></a> system variable).
          For the <code class="literal">daemon_example</code> plugin, it is
          compiled and installed when you build MySQL from source. It is
          also included in binary distributions. The build process
          produces a shared object library with a name of
          <code class="filename">libdaemon_example.so</code> (the
          <code class="filename">.so</code> suffix might differ depending on your
          platform).
        </p><p>
          To use the plugin, register it with the server. For example,
          to register the plugin at runtime, use this statement (adjust
          the <code class="filename">.so</code> suffix for your platform as
          necessary):
        </p><pre class="programlisting">
INSTALL PLUGIN daemon_example SONAME 'libdaemon_example.so';
</pre><p>
          For additional information about plugin loading, see
          <a class="xref" href="server-administration.html#server-plugin-loading" title="5.6.1 Installing and Uninstalling Plugins">Section 5.6.1, “Installing and Uninstalling Plugins”</a>.
        </p><p>
          To verify plugin installation, examine the
          <a class="link" href="information-schema.html#plugins-table" title="24.15 The INFORMATION_SCHEMA PLUGINS Table"><code class="literal">INFORMATION_SCHEMA.PLUGINS</code></a> table
          or use the <a class="link" href="sql-syntax.html#show-plugins" title="13.7.6.25 SHOW PLUGINS Syntax"><code class="literal">SHOW PLUGINS</code></a>
          statement. See <a class="xref" href="server-administration.html#obtaining-plugin-information" title="5.6.2 Obtaining Server Plugin Information">Section 5.6.2, “Obtaining Server Plugin Information”</a>.
        </p><p>
          While the plugin is loaded, it writes a heartbeat string at
          regular intervals to a file named
          <code class="filename">mysql-heartbeat.log</code> in the data
          directory. This file grows without limit, so after you have
          satistifed yourself that the plugin operates correctly, unload
          it:
        </p><pre class="programlisting">
UNINSTALL PLUGIN daemon_example;
</pre>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="writing-information-schema-plugins"></a>28.2.4.6 Writing INFORMATION_SCHEMA Plugins</h4>

</div>

</div>

</div>
<p>
          This section describes how to write a server-side
          <code class="literal">INFORMATION_SCHEMA</code> table plugin. For
          example code that implements such plugins, see the
          <code class="literal">sql/sql_show.cc</code> file of a MySQL source
          distribution. You can also look at the example plugins found
          in the <code class="literal">InnoDB</code> source. See the
          <code class="filename">handler/i_s.cc</code> and
          <code class="filename">handler/ha_innodb.cc</code> files within the
          <code class="literal">InnoDB</code> source tree (in the
          <code class="filename">storage/innobase</code> directory).
        </p><p>
          To write an <code class="literal">INFORMATION_SCHEMA</code> table
          plugin, include the following header files in the plugin
          source file. Other MySQL or general header files might also be
          needed, depending on the plugin capabilities and requirements.
        </p><pre class="programlisting">
#include &lt;sql_class.h&gt;
#include &lt;table.h&gt;
</pre><p>
          These header files are located in the <code class="filename">sql</code>
          directory of MySQL source distributions. They contain C++
          structures, so the source file for an
          <code class="literal">INFORMATION_SCHEMA</code> plugin must be compiled
          as C++ (not C) code.
        </p><p>
          The source file for the example plugin developed here is named
          <code class="filename">simple_i_s_table.cc</code>. It creates a simple
          <code class="literal">INFORMATION_SCHEMA</code> table named
          <code class="literal">SIMPLE_I_S_TABLE</code> that has two columns named
          <code class="literal">NAME</code> and <code class="literal">VALUE</code>. The
          general descriptor for a plugin library that implements the
          table looks like this:
        </p><pre class="programlisting">
mysql_declare_plugin(simple_i_s_library)
{
  MYSQL_INFORMATION_SCHEMA_PLUGIN,
  &amp;simple_table_info,                /* type-specific descriptor */
  "SIMPLE_I_S_TABLE",                /* table name */
  "Author Name",                     /* author */
  "Simple INFORMATION_SCHEMA table", /* description */
  PLUGIN_LICENSE_GPL,                /* license type */
  simple_table_init,                 /* init function */
  NULL,
  0x0100,                            /* version = 1.0 */
  NULL,                              /* no status variables */
  NULL,                              /* no system variables */
  NULL,                              /* no reserved information */
  0                                  /* no flags */
}
mysql_declare_plugin_end;
</pre><p>
          The <code class="literal">name</code> member
          (<code class="literal">SIMPLE_I_S_TABLE</code>) indicates the name to
          use for references to the plugin in statements such as
          <a class="link" href="sql-syntax.html#install-plugin" title="13.7.4.4 INSTALL PLUGIN Syntax"><code class="literal">INSTALL PLUGIN</code></a> or
          <a class="link" href="sql-syntax.html#uninstall-plugin" title="13.7.4.6 UNINSTALL PLUGIN Syntax"><code class="literal">UNINSTALL PLUGIN</code></a>. This is also
          the name displayed by <a class="link" href="sql-syntax.html#show-plugins" title="13.7.6.25 SHOW PLUGINS Syntax"><code class="literal">SHOW
          PLUGINS</code></a> or
          <a class="link" href="information-schema.html#plugins-table" title="24.15 The INFORMATION_SCHEMA PLUGINS Table"><code class="literal">INFORMATION_SCHEMA.PLUGINS</code></a>.
        </p><p>
          The <code class="literal">simple_table_info</code> member of the general
          descriptor points to the type-specific descriptor, which
          consists only of the type-specific API version number:
        </p><pre class="programlisting">
static struct st_mysql_information_schema simple_table_info =
{ MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION };
</pre><p>
          The general descriptor points to the initialization and
          deinitialization functions:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              The initialization function provides information about the
              table structure and a function that populates the table.
            </p></li><li class="listitem"><p>
              The deinitialization function performs any required
              cleanup. If no cleanup is needed, this descriptor member
              can be <code class="literal">NULL</code> (as in the example shown).
</p></li></ul>
</div>
<p>
          The initialization function should return 0 for success, 1 if
          an error occurs. The function receives a generic pointer,
          which it should interpret as a pointer to the table structure:
        </p><pre class="programlisting">
static int table_init(void *ptr)
{
  ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE*)ptr;

  schema_table-&gt;fields_info= simple_table_fields;
  schema_table-&gt;fill_table= simple_fill_table;
  return 0;
}
</pre><p>
          The function should set these two members of the table
          structure:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              <code class="literal">fields_info</code>: An array of
              <code class="literal">ST_FIELD_INFO</code> structures that contain
              information about each column.
            </p></li><li class="listitem"><p>
              <code class="literal">fill_table</code>: A function that populates
              the table.
</p></li></ul>
</div>
<p>
          The array pointed to by <code class="literal">fields_info</code> should
          contain one element per column of the
          <code class="literal">INFORMATION_SCHEMA</code> plus a terminating
          element. The following <code class="literal">simple_table_fields</code>
          array for the example plugin indicates that
          <code class="literal">SIMPLE_I_S_TABLE</code> has two columns.
          <code class="literal">NAME</code> is string-valued with a length of 10
          and <code class="literal">VALUE</code> is integer-valued with a display
          width of 20. The last structure marks the end of the array.
        </p><pre class="programlisting">
static ST_FIELD_INFO simple_table_fields[]=
{
  {"NAME", 10, MYSQL_TYPE_STRING, 0, 0 0, 0},
  {"VALUE", 6, MYSQL_TYPE_LONG, 0, MY_I_S_UNSIGNED, 0, 0},
  {0, 0, MYSQL_TYPE_NULL, 0, 0, 0, 0}
};
</pre><p>
          For more information about the column information structure,
          see the definition of <code class="literal">ST_FIELD_INFO</code> in the
          <code class="literal">table.h</code> header file. The permissible
          <code class="literal">MYSQL_TYPE_<em class="replaceable"><code>xxx</code></em></code>
          type values are those used in the C API; see
          <a class="xref" href="connectors-apis.html#c-api-data-structures" title="27.7.5 C API Data Structures">Section 27.7.5, “C API Data Structures”</a>.
        </p><p>
          The <code class="literal">fill_table</code> member should be set to a
          function that populates the table and returns 0 for success, 1
          if an error occurs. For the example plugin, the
          <code class="literal">simple_fill_table()</code> function looks like
          this:
        </p><pre class="programlisting">
static int simple_fill_table(THD *thd, TABLE_LIST *tables, Item *cond)
{
  TABLE *table= tables-&gt;table;

  table-&gt;field[0]-&gt;store("Name 1", 6, system_charset_info);
  table-&gt;field[1]-&gt;store(1);
  if (schema_table_store_record(thd, table))
    return 1;
  table-&gt;field[0]-&gt;store("Name 2", 6, system_charset_info);
  table-&gt;field[1]-&gt;store(2);
  if (schema_table_store_record(thd, table))
    return 1;
  return 0;
}
</pre><p>
          For each row of the <code class="literal">INFORMATION_SCHEMA</code>
          table, this function initializes each column, then calls
          <code class="literal">schema_table_store_record()</code> to install the
          row. The <code class="literal">store()</code> method arguments depend on
          the type of value to be stored. For column 0
          (<code class="literal">NAME</code>, a string),
          <code class="literal">store()</code> takes a pointer to a string, its
          length, and information about the character set of the string:
        </p><pre class="programlisting">
store(const char *to, uint length, CHARSET_INFO *cs);
</pre><p>
          For column 1 (<code class="literal">VALUE</code>, an integer),
          <code class="literal">store()</code> takes the value and a flag
          indicating whether it is unsigned:
        </p><pre class="programlisting">
store(longlong nr, bool unsigned_value);
</pre><p>
          For other examples of how to populate
          <code class="literal">INFORMATION_SCHEMA</code> tables, search for
          instances of <code class="literal">schema_table_store_record()</code> in
          <code class="filename">sql_show.cc</code>.
        </p><p>
          To compile and install a plugin library file, use the
          instructions in <a class="xref" href="extending-mysql.html#compiling-plugin-libraries" title="28.2.4.3 Compiling and Installing Plugin Libraries">Section 28.2.4.3, “Compiling and Installing Plugin Libraries”</a>.
          To make the library file available for use, install it in the
          plugin directory (the directory named by the
          <a class="link" href="server-administration.html#sysvar_plugin_dir"><code class="literal">plugin_dir</code></a> system variable).
        </p><p>
          To test the plugin, install it:
        </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>INSTALL PLUGIN SIMPLE_I_S_TABLE SONAME 'simple_i_s_table.so';</code></strong>
</pre><p>
          Verify that the table is present:
        </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES</code></strong>
    -&gt; <strong class="userinput"><code>WHERE TABLE_NAME = 'SIMPLE_I_S_TABLE';</code></strong>
+------------------+
| TABLE_NAME       |
+------------------+
| SIMPLE_I_S_TABLE |
+------------------+
</pre><p>
          Try to select from it:
        </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>SELECT * FROM INFORMATION_SCHEMA.SIMPLE_I_S_TABLE;</code></strong>
+--------+-------+
| NAME   | VALUE |
+--------+-------+
| Name 1 |     1 |
| Name 2 |     2 |
+--------+-------+
</pre><p>
          Uninstall it:
        </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>UNINSTALL PLUGIN SIMPLE_I_S_TABLE;</code></strong>
</pre>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="writing-semisynchronous-replication-plugins"></a>28.2.4.7 Writing Semisynchronous Replication Plugins</h4>

</div>

</div>

</div>
<p>
          This section describes how to write server-side
          semisynchronous replication plugins, using the example plugins
          found in the <code class="literal">plugin/semisync</code> directory of
          MySQL source distributions. That directory contains the source
          files for master and slave plugins named
          <code class="literal">rpl_semi_sync_master</code> and
          <code class="literal">rpl_semi_sync_slave</code>. The information here
          covers only how to set up the plugin framework. For details
          about how the plugins implement replication functions, see the
          source.
        </p><p>
          To write a semisynchronous replication plugin, include the
          following header file in the plugin source file. Other MySQL
          or general header files might also be needed, depending on the
          plugin capabilities and requirements.
        </p><pre class="programlisting">
#include &lt;mysql/plugin.h&gt;
</pre><p>
          <code class="filename">plugin.h</code> defines the
          <code class="literal">MYSQL_REPLICATION_PLUGIN</code> server plugin type
          and the data structures needed to declare the plugin.
        </p><p>
          For the master side,
          <code class="filename">semisync_master_plugin.cc</code> contains this
          general descriptor for a plugin named
          <code class="literal">rpl_semi_sync_master</code>:
        </p><pre class="programlisting">
mysql_declare_plugin(semi_sync_master)
{
  MYSQL_REPLICATION_PLUGIN,
  &amp;semi_sync_master_plugin,
  "rpl_semi_sync_master",
  "He Zhenxing",
  "Semi-synchronous replication master",
  PLUGIN_LICENSE_GPL,
  semi_sync_master_plugin_init, /* Plugin Init */
  semi_sync_master_plugin_deinit, /* Plugin Deinit */
  0x0100 /* 1.0 */,
  semi_sync_master_status_vars, /* status variables */
  semi_sync_master_system_vars, /* system variables */
  NULL,                         /* config options */
  0,                            /* flags */
}
mysql_declare_plugin_end;
</pre><p>
          For the slave side,
          <code class="filename">semisync_slave_plugin.cc</code> contains this
          general descriptor for a plugin named
          <code class="literal">rpl_semi_sync_slave</code>:
        </p><pre class="programlisting">
mysql_declare_plugin(semi_sync_slave)
{
  MYSQL_REPLICATION_PLUGIN,
  &amp;semi_sync_slave_plugin,
  "rpl_semi_sync_slave",
  "He Zhenxing",
  "Semi-synchronous replication slave",
  PLUGIN_LICENSE_GPL,
  semi_sync_slave_plugin_init, /* Plugin Init */
  semi_sync_slave_plugin_deinit, /* Plugin Deinit */
  0x0100 /* 1.0 */,
  semi_sync_slave_status_vars,  /* status variables */
  semi_sync_slave_system_vars,  /* system variables */
  NULL,                         /* config options */
  0,                            /* flags */
}
mysql_declare_plugin_end;
</pre><p>
          For both the master and slave plugins, the general descriptor
          has pointers to the type-specific descriptor, the
          initialization and deinitialization functions, and to the
          status and system variables implemented by the plugin. For
          information about variable setup, see
          <a class="xref" href="extending-mysql.html#plugin-status-system-variables" title="28.2.4.2.2 Server Plugin Status and System Variables">Section 28.2.4.2.2, “Server Plugin Status and System Variables”</a>. The
          following remarks discuss the type-specific descriptor and the
          initialization and deinitialization functions for the master
          plugin but apply similarly to the slave plugin.
        </p><p>
          The <code class="literal">semi_sync_master_plugin</code> member of the
          master general descriptor points to the type-specific
          descriptor, which consists only of the type-specific API
          version number:
        </p><pre class="programlisting">
struct Mysql_replication semi_sync_master_plugin= {
  MYSQL_REPLICATION_INTERFACE_VERSION
};
</pre><p>
          The initialization and deinitialization function declarations
          look like this:
        </p><pre class="programlisting">
static int semi_sync_master_plugin_init(void *p);
static int semi_sync_master_plugin_deinit(void *p);
</pre><p>
          The initialization function uses the pointer to register
          transaction and binary logging <span class="quote">“<span class="quote">observers</span>”</span> with
          the server. After successful initialization, the server takes
          care of invoking the observers at the appropriate times. (For
          details on the observers, see the source files.) The
          deinitialization function cleans up by deregistering the
          observers. Each function returns 0 for success or 1 if an
          error occurs.
        </p><p>
          To compile and install a plugin library file, use the
          instructions in <a class="xref" href="extending-mysql.html#compiling-plugin-libraries" title="28.2.4.3 Compiling and Installing Plugin Libraries">Section 28.2.4.3, “Compiling and Installing Plugin Libraries”</a>.
          To make the library file available for use, install it in the
          plugin directory (the directory named by the
          <a class="link" href="server-administration.html#sysvar_plugin_dir"><code class="literal">plugin_dir</code></a> system variable).
          For the <code class="literal">rpl_semi_sync_master</code> and
          <code class="literal">rpl_semi_sync_slave</code> plugins, they are
          compiled and installed when you build MySQL from source. They
          are also included in binary distributions. The build process
          produces shared object libraries with names of
          <code class="filename">semisync_master.so</code> and
          <code class="filename">semisync_slave.so</code> (the
          <code class="filename">.so</code> suffix might differ depending on your
          platform).
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="writing-audit-plugins"></a>28.2.4.8 Writing Audit Plugins</h4>

</div>

</div>

</div>
<p>
          This section describes how to write a server-side audit
          plugin, using the example plugin found in the
          <code class="literal">plugin/audit_null</code> directory of MySQL source
          distributions. The <code class="filename">audit_null.c</code> and
          <code class="filename">audit_null_variables.h</code> source files in
          that directory implement an audit plugin named
          <code class="literal">NULL_AUDIT</code>.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
            Other examples of plugins that use the audit plugin API are
            the query rewrite plugin (see
            <a class="xref" href="server-administration.html#rewriter-query-rewrite-plugin" title="5.6.4 The Rewriter Query Rewrite Plugin">Section 5.6.4, “The Rewriter Query Rewrite Plugin”</a>) and the
            Version Tokens plugin (see
            <a class="xref" href="server-administration.html#version-tokens" title="5.6.5 Version Tokens">Section 5.6.5, “Version Tokens”</a>).
</p>
</div>
<p>
          Within the server, the pluggable audit interface is
          implemented in the <code class="filename">sql_audit.h</code> and
          <code class="filename">sql_audit.cc</code> files in the
          <code class="filename">sql</code> directory of MySQL source
          distributions. Additionally, several places in the server call
          the audit interface when an auditable event occurs, so that
          registered audit plugins can be notified about the event if
          necessary. To see where such calls occur, search the server
          source files for invocations of functions with names of the
          form
          <code class="filename">mysql_audit_<em class="replaceable"><code>xxx</code></em>()</code>.
          Audit notification occurs for server operations such as these:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              Client connect and disconnect events
            </p></li><li class="listitem"><p>
              Writing a message to the general query log (if the log is
              enabled)
            </p></li><li class="listitem"><p>
              Writing a message to the error log
            </p></li><li class="listitem"><p>
              Sending a query result to a client
</p></li></ul>
</div>
<p>
          To write an audit plugin, include the following header file in
          the plugin source file. Other MySQL or general header files
          might also be needed, depending on the plugin capabilities and
          requirements.
        </p><pre class="programlisting">
#include &lt;mysql/plugin_audit.h&gt;
</pre><p>
          <code class="filename">plugin_audit.h</code> includes
          <code class="filename">plugin.h</code>, so you need not include the
          latter file explicitly. <code class="filename">plugin.h</code> defines
          the <code class="literal">MYSQL_AUDIT_PLUGIN</code> server plugin type
          and the data structures needed to declare the plugin.
          <code class="filename">plugin_audit.h</code> defines data structures
          specific to audit plugins.
</p>
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h5 class="title"><a name="writing-audit-plugins-general-descriptor"></a>Audit Plugin General Descriptor</h5>
</div>
</div>
</div>
<p>
            An audit plugin, like any MySQL server plugin, has a general
            plugin descriptor (see
            <a class="xref" href="extending-mysql.html#server-plugin-descriptors" title="28.2.4.2.1 Server Plugin Library and Plugin Descriptors">Section 28.2.4.2.1, “Server Plugin Library and Plugin Descriptors”</a>) and a
            type-specific plugin descriptor. In
            <code class="filename">audit_null.c</code>, the general descriptor
            for <code class="literal">audit_null</code> looks like this:
          </p><pre class="programlisting">
mysql_declare_plugin(audit_null)
{
  MYSQL_AUDIT_PLUGIN,         /* type                            */
  &amp;audit_null_descriptor,     /* descriptor                      */
  "NULL_AUDIT",               /* name                            */
  "Oracle Corp",              /* author                          */
  "Simple NULL Audit",        /* description                     */
  PLUGIN_LICENSE_GPL,
  audit_null_plugin_init,     /* init function (when loaded)     */
  audit_null_plugin_deinit,   /* deinit function (when unloaded) */
  0x0003,                     /* version                         */
  simple_status,              /* status variables                */
  system_variables,           /* system variables                */
  NULL,
  0,
}
mysql_declare_plugin_end;
</pre><p>
            The first member, <code class="literal">MYSQL_AUDIT_PLUGIN</code>,
            identifies this plugin as an audit plugin.
          </p><p>
            <code class="literal">audit_null_descriptor</code> points to the
            type-specific plugin descriptor, described later.
          </p><p>
            The <code class="literal">name</code> member
            (<code class="literal">NULL_AUDIT</code>) indicates the name to use
            for references to the plugin in statements such as
            <a class="link" href="sql-syntax.html#install-plugin" title="13.7.4.4 INSTALL PLUGIN Syntax"><code class="literal">INSTALL PLUGIN</code></a> or
            <a class="link" href="sql-syntax.html#uninstall-plugin" title="13.7.4.6 UNINSTALL PLUGIN Syntax"><code class="literal">UNINSTALL PLUGIN</code></a>. This is
            also the name displayed by
            <a class="link" href="information-schema.html#plugins-table" title="24.15 The INFORMATION_SCHEMA PLUGINS Table"><code class="literal">INFORMATION_SCHEMA.PLUGINS</code></a> or
            <a class="link" href="sql-syntax.html#show-plugins" title="13.7.6.25 SHOW PLUGINS Syntax"><code class="literal">SHOW PLUGINS</code></a>.
          </p><p>
            The <code class="literal">audit_null_plugin_init</code> initialization
            function performs plugin initialization when the plugin is
            loaded. The <code class="literal">audit_null_plugin_deinit</code>
            function performs cleanup when the plugin is unloaded.
          </p><p>
            The general plugin descriptor also refers to
            <code class="literal">simple_status</code> and
            <code class="literal">system_variables</code>, structures that expose
            several status and system variables. When the plugin is
            enabled, these variables can be inspected using
            <code class="literal">SHOW</code> statements
            (<a class="link" href="sql-syntax.html#show-status" title="13.7.6.35 SHOW STATUS Syntax"><code class="literal">SHOW STATUS</code></a>,
            <a class="link" href="sql-syntax.html#show-variables" title="13.7.6.39 SHOW VARIABLES Syntax"><code class="literal">SHOW VARIABLES</code></a>) or the
            appropriate Performance Schema tables.
          </p><p>
            The <code class="literal">simple_status</code> structure declares
            several status variables with names of the form
            <code class="literal">Audit_null_<em class="replaceable"><code>xxx</code></em></code>.
            <code class="literal">NULL_AUDIT</code> increments the
            <code class="literal">Audit_null_called</code> status variable for
            every notification that it receives. The other status
            variables are more specific and
            <code class="literal">NULL_AUDIT</code> increments them only for
            notifications of specific events.
          </p><p>
            <code class="literal">system_variables</code> is an array of system
            variable elements, each of which is defined using a
            <code class="literal">MYSQL_THDVAR_<em class="replaceable"><code>xxx</code></em></code>
            macro. These system variables have names of the form
            <code class="literal">null_audit_<em class="replaceable"><code>xxx</code></em></code>.
            These variables can be used to communicate with the plugin
            at runtime.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="writing-audit-plugins-type-specific-descriptor"></a>Audit Plugin Type-Specific Descriptor</h5>

</div>

</div>

</div>
<p>
            The <code class="literal">audit_null_descriptor</code> value in the
            general plugin descriptor points to the type-specific plugin
            descriptor. For audit plugins, this descriptor has the
            following structure (defined in
            <code class="filename">plugin_audit.h</code>):
          </p><pre class="programlisting">
struct st_mysql_audit
{
  int interface_version;
  void (*release_thd)(MYSQL_THD);
  int (*event_notify)(MYSQL_THD, mysql_event_class_t, const void *);
  unsigned long class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
};
</pre><p>
            The type-specific descriptor for audit plugins has these
            members:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                <code class="literal">interface_version</code>: By convention,
                type-specific plugin descriptors begin with the
                interface version for the given plugin type. The server
                checks <code class="literal">interface_version</code> when it
                loads the plugin to see whether the plugin is compatible
                with it. For audit plugins, the value of the
                <code class="literal">interface_version</code> member is
                <code class="literal">MYSQL_AUDIT_INTERFACE_VERSION</code>
                (defined in <code class="literal">plugin_audit.h</code>).
              </p></li><li class="listitem"><p>
                <code class="literal">release_thd</code>: A function that the
                server calls to inform the plugin that it is being
                dissociated from its thread context. This should be
                <code class="literal">NULL</code> if there is no such function.
              </p></li><li class="listitem"><p>
                <code class="literal">event_notify</code>: A function that the
                server calls to notify the plugin that an auditable
                event has occurred. This function should not be
                <code class="literal">NULL</code>; that would not make sense
                because no auditing would occur.
              </p></li><li class="listitem"><p>
                <code class="literal">class_mask</code>: An array of
                <code class="literal">MYSQL_AUDIT_CLASS_MASK_SIZE</code> elements.
                Each element specifies a bitmask for a given event class
                to indicate the subclasses for which the plugin wants
                notification. (This is how the plugin
                <span class="quote">“<span class="quote">subscribes</span>”</span> to events of interest.) An
                element should be 0 to ignore events for the
                corresponding event class.
</p></li></ul>
</div>
<p>
            The server uses the <code class="literal">event_notify</code> and
            <code class="literal">release_thd</code> functions together. They are
            called within the context of a specific thread, and a thread
            might perform an activity that produces several event
            notifications. The first time the server calls
            <code class="literal">event_notify</code> for a thread, it creates a
            binding of the plugin to the thread. The plugin cannot be
            uninstalled while this binding exists. When no more events
            for the thread will occur, the server informs the plugin of
            this by calling the <code class="literal">release_thd</code> function,
            and then destroys the binding. For example, when a client
            issues a statement, the thread processing the statement
            might notify audit plugins about the result set produced by
            the statement and about the statement being logged. After
            these notifications occur, the server releases the plugin
            before putting the thread to sleep until the client issues
            another statement.
          </p><p>
            This design enables the plugin to allocate resources needed
            for a given thread in the first call to the
            <code class="literal">event_notify</code> function and release them in
            the <code class="literal">release_thd</code> function:
          </p><pre class="programlisting">
event_notify function:
  if memory is needed to service the thread
    allocate memory
  ... rest of notification processing ...

release_thd function:
  if memory was allocated
    release memory
  ... rest of release processing ...
</pre><p>
            That is more efficient than allocating and releasing memory
            repeatedly in the notification function.
          </p><p>
            For the <code class="literal">NULL_AUDIT</code> audit plugin, the
            type-specific plugin descriptor looks like this:
          </p><pre class="programlisting">
static struct st_mysql_audit audit_null_descriptor=
{
  MYSQL_AUDIT_INTERFACE_VERSION,                    /* interface version    */
  NULL,                                             /* release_thd function */
  audit_null_notify,                                /* notify function      */
  { (unsigned long) MYSQL_AUDIT_GENERAL_ALL,
    (unsigned long) MYSQL_AUDIT_CONNECTION_ALL,
    (unsigned long) MYSQL_AUDIT_PARSE_ALL,
    (unsigned long) MYSQL_AUDIT_AUTHORIZATION_ALL,
    (unsigned long) MYSQL_AUDIT_TABLE_ACCESS_ALL,
    (unsigned long) MYSQL_AUDIT_GLOBAL_VARIABLE_ALL,
    (unsigned long) MYSQL_AUDIT_SERVER_STARTUP_ALL,
    (unsigned long) MYSQL_AUDIT_SERVER_SHUTDOWN_ALL,
    (unsigned long) MYSQL_AUDIT_COMMAND_ALL,
    (unsigned long) MYSQL_AUDIT_QUERY_ALL,
    (unsigned long) MYSQL_AUDIT_STORED_PROGRAM_ALL }
};
</pre><p>
            The server calls <code class="literal">audit_null_notify()</code> to
            pass audit event information to the plugin. There is no
            <code class="literal">release_thd</code> function.
          </p><p>
            The <code class="literal">class_mask</code> member is an array that
            indicates which event classes the plugin subscribes to. As
            shown, the array contents subscribe to all subclasses of all
            event classes that are available. To ignore all
            notifications for a given event class, specify the
            corresponding <code class="literal">class_mask</code> element as 0.
          </p><p>
            The number of <code class="literal">class_mask</code> elements
            corresponds to the number of event classes, each of which is
            listed in the <code class="literal">mysql_event_class_t</code>
            enumeration defined in <code class="filename">plugin_audit.h</code>:
          </p><pre class="programlisting">
typedef enum
{
  MYSQL_AUDIT_GENERAL_CLASS          = 0,
  MYSQL_AUDIT_CONNECTION_CLASS       = 1,
  MYSQL_AUDIT_PARSE_CLASS            = 2,
  MYSQL_AUDIT_AUTHORIZATION_CLASS    = 3,
  MYSQL_AUDIT_TABLE_ACCESS_CLASS     = 4,
  MYSQL_AUDIT_GLOBAL_VARIABLE_CLASS  = 5,
  MYSQL_AUDIT_SERVER_STARTUP_CLASS   = 6,
  MYSQL_AUDIT_SERVER_SHUTDOWN_CLASS  = 7,
  MYSQL_AUDIT_COMMAND_CLASS          = 8,
  MYSQL_AUDIT_QUERY_CLASS            = 9,
  MYSQL_AUDIT_STORED_PROGRAM_CLASS   = 10,
  /* This item must be last in the list. */
  MYSQL_AUDIT_CLASS_MASK_SIZE
} mysql_event_class_t;
</pre><p>
            For any given event class,
            <code class="filename">plugin_audit.h</code> defines bitmask symbols
            for individual event subclasses, as well as an
            <code class="literal"><em class="replaceable"><code>xxx</code></em>_ALL</code> symbol
            that is the union of the all subclass bitmasks. For example,
            for <code class="literal">MYSQL_AUDIT_CONNECTION_CLASS</code> (the
            class that covers connect and disconnect events),
            <code class="filename">plugin_audit.h</code> defines these symbols:
          </p><pre class="programlisting">
typedef enum
{
  /** occurs after authentication phase is completed. */
  MYSQL_AUDIT_CONNECTION_CONNECT          = 1 &lt;&lt; 0,
  /** occurs after connection is terminated. */
  MYSQL_AUDIT_CONNECTION_DISCONNECT       = 1 &lt;&lt; 1,
  /** occurs after COM_CHANGE_USER RPC is completed. */
  MYSQL_AUDIT_CONNECTION_CHANGE_USER      = 1 &lt;&lt; 2,
  /** occurs before authentication. */
  MYSQL_AUDIT_CONNECTION_PRE_AUTHENTICATE = 1 &lt;&lt; 3
} mysql_event_connection_subclass_t;

#define MYSQL_AUDIT_CONNECTION_ALL (MYSQL_AUDIT_CONNECTION_CONNECT | \
                                    MYSQL_AUDIT_CONNECTION_DISCONNECT | \
                                    MYSQL_AUDIT_CONNECTION_CHANGE_USER | \
                                    MYSQL_AUDIT_CONNECTION_PRE_AUTHENTICATE)
</pre><p>
            To subscribe to all subclasses of the connection event class
            (as the <code class="literal">NULL_AUDIT</code> plugin does), a plugin
            specifies <code class="literal">MYSQL_AUDIT_CONNECTION_ALL</code> in
            the corresponding <code class="literal">class_mask</code> element
            (<code class="literal">class_mask[1]</code> in this case). To
            subscribe to only some subclasses, the plugin sets the
            <code class="literal">class_mask</code> element to the union of the
            subclasses of interest. For example, to subscribe only to
            the connect and change-user subclasses, the plugin sets
            <code class="literal">class_mask[1]</code> to this value:
          </p><pre class="programlisting">
MYSQL_AUDIT_CONNECTION_CONNECT | MYSQL_AUDIT_CONNECTION_CHANGE_USER
</pre>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="writing-audit-plugins-notification-function"></a>Audit Plugin Notification Function</h5>

</div>

</div>

</div>
<p>
            Most of the work for an audit plugin occurs in the
            notification function (the <code class="literal">event_notify</code>
            member of the type-specific plugin descriptor). The server
            calls this function for each auditable event. Audit plugin
            notification functions have this prototype:
          </p><pre class="programlisting">
int (*event_notify)(MYSQL_THD, mysql_event_class_t, const void *);
</pre><p>
            The second and third parameters of the
            <code class="literal">event_notify</code> function prototype represent
            the event class and a generic pointer to an event structure.
            (Events in different classes have different structures. The
            notification function can use the event class value to
            determine which event structure applies.) The function
            processes the event and returns a status indicating whether
            the server should continue processing the event or terminate
            it.
          </p><p>
            For <code class="literal">NULL_AUDIT</code>, the notification function
            is <code class="literal">audit_null_notify()</code>. This function
            increments a global event counter (which the plugin exposes
            as the value of the <code class="literal">Audit_null_called</code>
            status value), and then examines the event class to
            determine how to process the event structure:
          </p><pre class="programlisting">
static int audit_null_notify(MYSQL_THD thd __attribute__((unused)),
                             mysql_event_class_t event_class,
                             const void *event)
{
  ...

  number_of_calls++;

  if (event_class == MYSQL_AUDIT_GENERAL_CLASS)
  {
    const struct mysql_event_general *event_general=
                                    (const struct mysql_event_general *)event;
    ...
  }
  else if (event_class == MYSQL_AUDIT_CONNECTION_CLASS)
  {
    const struct mysql_event_connection *event_connection=
                                (const struct mysql_event_connection *) event;
    ...

  }
  else if (event_class == MYSQL_AUDIT_PARSE_CLASS)
  {
    const struct mysql_event_parse *event_parse =
                                      (const struct mysql_event_parse *)event;
    ...
  }
  ...
}
</pre><p>
            The notification function interprets the
            <code class="literal">event</code> argument according to the value of
            <code class="literal">event_class</code>. The <code class="literal">event</code>
            argument is a generic pointer to the event record, the
            structure of which differs per event class. (The
            <code class="filename">plugin_audit.h</code> file contains the
            structures that define the contents of each event class.)
            For each class, <code class="literal">audit_null_notify()</code> casts
            the event to the appropriate class-specific structure and
            then checks its subclass to determine which subclass counter
            to increment. For example, the code to handle events in the
            connection-event class looks like this:
          </p><pre class="programlisting">
else if (event_class == MYSQL_AUDIT_CONNECTION_CLASS)
{
  const struct mysql_event_connection *event_connection=
                              (const struct mysql_event_connection *) event;

  switch (event_connection-&gt;event_subclass)
  {
  case MYSQL_AUDIT_CONNECTION_CONNECT:
    number_of_calls_connection_connect++;
    break;
  case MYSQL_AUDIT_CONNECTION_DISCONNECT:
    number_of_calls_connection_disconnect++;
    break;
  case MYSQL_AUDIT_CONNECTION_CHANGE_USER:
    number_of_calls_connection_change_user++;
    break;
  case MYSQL_AUDIT_CONNECTION_PRE_AUTHENTICATE:
    number_of_calls_connection_pre_authenticate++;
      break;
  default:
    break;
  }
}
</pre>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
              The general event class
              (<code class="literal">MYSQL_AUDIT_GENERAL_CLASS</code>) is
              deprecated as of MySQL 5.7.9 and will be removed in a
              future MySQL release. To reduce plugin overhead, it is
              preferable to subscribe only to the more specific event
              classes of interest.
</p>
</div>
<p>
            For some event classes, the <code class="literal">NULL_AUDIT</code>
            plugin performs other processing in addition to incrementing
            a counter. In any case, when the notification function
            finishes processing the event, it should return a status
            indicating whether the server should continue processing the
            event or terminate it.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="writing-audit-plugins-error-handling"></a>Audit Plugin Error Handling</h5>

</div>

</div>

</div>
<p>
            Audit plugin notification functions can report a status
            value for the current event two ways:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                Use the notification function return value. In this
                case, the function returns zero if the server should
                continue processing the event, or nonzero if the server
                should terminate the event.
              </p></li><li class="listitem"><p>
                Call the <code class="literal">my_message()</code> function to set
                the error state before returning from the notification
                function. In this case, the notification function return
                value is ignored and the server terminates event
                processing with an error. The
                <code class="literal">my_message()</code> arguments indicate which
                error to report, and its message. For example:
              </p><pre class="programlisting">
my_message(ER_AUDIT_API_ABORT, "This is my error message.", MYF(0));
</pre><p>
                Some events cannot be aborted. A nonzero return value is
                not taken into consideration and the
                <code class="literal">my_message()</code> error call must follow
                an <code class="literal">is_error()</code> check. For example:
              </p><pre class="programlisting">
if (!thd-&gt;get_stmt_da()-&gt;is_error())
{
  my_message(ER_AUDIT_API_ABORT, "This is my error message.", MYF(0));
}
</pre></li></ul>
</div>
<p>
            Some events cannot be terminated:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                <code class="literal">MYSQL_AUDIT_CONNECTION_DISCONNECT</code>:
                The server cannot prevent a client from disconnecting.
              </p></li><li class="listitem"><p>
                <code class="literal">MYSQL_AUDIT_COMMAND_END</code>: This event
                provides the status of a command that has finished
                executing, so there is no purpose to terminating it.
</p></li></ul>
</div>
<p>
            If an audit plugin returns nonzero status for a
            nonterminable event, the server ignores the status and
            continues processing the event. This is also true if an
            audit plugin uses the <code class="literal">my_message()</code>
            function to terminate a nonterminable event.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="writing-audit-plugins-usage"></a>Audit Plugin Usage</h5>

</div>

</div>

</div>
<p>
            To compile and install a plugin library file, use the
            instructions in
            <a class="xref" href="extending-mysql.html#compiling-plugin-libraries" title="28.2.4.3 Compiling and Installing Plugin Libraries">Section 28.2.4.3, “Compiling and Installing Plugin Libraries”</a>. To make the
            library file available for use, install it in the plugin
            directory (the directory named by the
            <a class="link" href="server-administration.html#sysvar_plugin_dir"><code class="literal">plugin_dir</code></a> system
            variable). For the <code class="literal">NULL_AUDIT</code> plugin, it
            is compiled and installed when you build MySQL from source.
            It is also included in binary distributions. The build
            process produces a shared object library with a name of
            <code class="filename">adt_null.so</code> (the
            <code class="filename">.so</code> suffix might differ depending on
            your platform).
          </p><p>
            To register the plugin at runtime, use this statement
            (adjust the <code class="filename">.so</code> suffix for your
            platform as necessary):
          </p><pre class="programlisting">
INSTALL PLUGIN NULL_AUDIT SONAME 'adt_null.so';
</pre><p>
            For additional information about plugin loading, see
            <a class="xref" href="server-administration.html#server-plugin-loading" title="5.6.1 Installing and Uninstalling Plugins">Section 5.6.1, “Installing and Uninstalling Plugins”</a>.
          </p><p>
            To verify plugin installation, examine the
            <a class="link" href="information-schema.html#plugins-table" title="24.15 The INFORMATION_SCHEMA PLUGINS Table"><code class="literal">INFORMATION_SCHEMA.PLUGINS</code></a>
            table or use the <a class="link" href="sql-syntax.html#show-plugins" title="13.7.6.25 SHOW PLUGINS Syntax"><code class="literal">SHOW PLUGINS</code></a>
            statement. See
            <a class="xref" href="server-administration.html#obtaining-plugin-information" title="5.6.2 Obtaining Server Plugin Information">Section 5.6.2, “Obtaining Server Plugin Information”</a>.
          </p><p>
            While the audit plugin is installed, it exposes status
            variables that indicate the events for which the plugin has
            been called:
          </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>SHOW STATUS LIKE 'Audit_null%';</code></strong>
+----------------------------------------+--------+
| Variable_name                          | Value  |
+----------------------------------------+--------+
| Audit_null_authorization_column        | 0      |
| Audit_null_authorization_db            | 0      |
| Audit_null_authorization_procedure     | 0      |
| Audit_null_authorization_proxy         | 0      |
| Audit_null_authorization_table         | 0      |
| Audit_null_authorization_user          | 0      |
| Audit_null_called                      | 185547 |
| Audit_null_command_end                 | 20999  |
| Audit_null_command_start               | 21001  |
| Audit_null_connection_change_user      | 0      |
| Audit_null_connection_connect          | 5823   |
| Audit_null_connection_disconnect       | 5818   |
| Audit_null_connection_pre_authenticate | 5823   |
| Audit_null_general_error               | 1      |
| Audit_null_general_log                 | 26559  |
| Audit_null_general_result              | 19922  |
| Audit_null_general_status              | 21000  |
| Audit_null_global_variable_get         | 0      |
| Audit_null_global_variable_set         | 0      |
| Audit_null_parse_postparse             | 14648  |
| Audit_null_parse_preparse              | 14648  |
| Audit_null_query_nested_start          | 6      |
| Audit_null_query_nested_status_end     | 6      |
| Audit_null_query_start                 | 14648  |
| Audit_null_query_status_end            | 14647  |
| Audit_null_server_shutdown             | 0      |
| Audit_null_server_startup              | 1      |
| Audit_null_table_access_delete         | 104    |
| Audit_null_table_access_insert         | 2839   |
| Audit_null_table_access_read           | 97842  |
| Audit_null_table_access_update         | 278    |
+----------------------------------------+--------+
</pre><p>
            <code class="literal">Audit_null_called</code> counts all events, and
            the other variables count instances of specific event
            subclasses. For example, the preceding
            <a class="link" href="sql-syntax.html#show-status" title="13.7.6.35 SHOW STATUS Syntax"><code class="literal">SHOW STATUS</code></a> statement causes
            the server to send a result to the client and to write a
            message to the general query log if that log is enabled.
            Thus, a client that issues the statement repeatedly causes
            <code class="literal">Audit_null_called</code>,
            <code class="literal">Audit_null_general_result</code>, and
            <code class="literal">Audit_null_general_log</code> to be incremented
            each time. Notifications occur whether or not that log is
            enabled.
          </p><p>
            The status variables values are aggregated across all
            sessions. There are no counters for individual sessions.
          </p><p>
            <code class="literal">NULL_AUDIT</code> exposes several system
            variables that enable communication with the plugin at
            runtime:
          </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>SHOW VARIABLES LIKE 'null_audit%';</code></strong>
+------------------------------------+-------+
| Variable_name                      | Value |
+------------------------------------+-------+
| null_audit_abort_message           |       |
| null_audit_abort_value             | 1     |
| null_audit_event_order_check       |       |
| null_audit_event_order_check_exact | 1     |
| null_audit_event_order_started     | 0     |
| null_audit_event_record            |       |
| null_audit_event_record_def        |       |
+------------------------------------+-------+
</pre><p>
            To check the order of audit API calls, set the
            <code class="literal">null_audit_event_order_check</code> variable to
            the expected event order. For example:
          </p><pre class="programlisting">
SET null_audit_event_order_check =
      'MYSQL_AUDIT_CONNECTION_PRE_AUTHENTICATE;;;'
      'MYSQL_AUDIT_GENERAL_LOG;;;'
      'MYSQL_AUDIT_CONNECTION_CONNECT;;';
</pre><p>
            The statement takes advantage of the SQL syntax that
            concatenates adjacent strings into a single string.
          </p><p>
            The format of the value is:
          </p><pre class="programlisting">
'<em class="replaceable"><code>event_name</code></em>;<em class="replaceable"><code>event_data</code></em>;<em class="replaceable"><code>command</code></em>' [';<em class="replaceable"><code>event_name</code></em>;<em class="replaceable"><code>event_data</code></em>;<em class="replaceable"><code>command</code></em>'] ...
</pre><p>
            After the event order is matched, the
            <code class="literal">null_audit_event_order_check</code> value is
            replaced with a value of <code class="literal">EVENT-ORDER-OK</code>.
          </p><p>
            Specifying a command value of <code class="literal">ABORT_RET</code>
            makes it possible to abort the audit API call on the
            specified event. The following example aborts
            <a class="link" href="sql-syntax.html#insert" title="13.2.6 INSERT Syntax"><code class="literal">INSERT</code></a> statement execution
            when its <code class="literal">MYSQL_AUDIT_QUERY_STATUS_END</code>
            event occurs:
          </p><pre class="programlisting">
SET null_audit_event_order_check =
   'MYSQL_AUDIT_COMMAND_START;command_id="3";;'
   'MYSQL_AUDIT_GENERAL_LOG;;;'
   'MYSQL_AUDIT_QUERY_START;;;'
   'MYSQL_AUDIT_QUERY_STATUS_END;;ABORT_RET';
</pre><p>
            After the audit plugin matches the preceding sequence, it
            aborts event processing and sends an error message to the
            client:
          </p><pre class="programlisting">
ERROR 3164 (HY000): Aborted by Audit API ('MYSQL_AUDIT_QUERY_STATUS_END';1).
</pre><p>
            Returning a nonzero value from the audit API notification
            routine is the standard way to abort event execution. It is
            also possible to specify a custom error code by setting the
            <code class="literal">null_audit_abort_value</code> variable to the
            value that the notification routine should return:
          </p><pre class="programlisting">
SET null_audit_abort_value = 123;
</pre><p>
            Aborting a sequence results in a standard message with the
            custom error code. Suppose that you set audit log system
            variables like this:
          </p><pre class="programlisting">
SET null_audit_abort_value = 123;
SET null_audit_event_order_check =
    'MYSQL_AUDIT_COMMAND_START;command_id="3";;'
    'MYSQL_AUDIT_GENERAL_LOG;;;'
    'MYSQL_AUDIT_QUERY_START;;ABORT_RET';
</pre><p>
            Then execution of <code class="literal">SELECT 1</code> results in
            this error:
          </p><pre class="programlisting">
ERROR 3164 (HY000): Aborted by Audit API ('MYSQL_AUDIT_QUERY_START';123).
</pre><p>
            An event can be also aborted with a custom message,
            specified by setting the
            <code class="literal">null_audit_abort_message</code> variable:
            Suppose that you set audit log system variables like this:
          </p><pre class="programlisting">
SET null_audit_abort_message = 'Custom error text.';
SET null_audit_event_order_check =
    'MYSQL_AUDIT_COMMAND_START;command_id="3";;'
    'MYSQL_AUDIT_GENERAL_LOG;;;'
    'MYSQL_AUDIT_QUERY_START;;ABORT_RET';
</pre><p>
            Then aborting a sequence results in the following error:
          </p><pre class="programlisting">
ERROR 3164 (HY000): Custom error text.
</pre><p>
            For test-creation purposes, it is possible to record events
            that pass through the plugin. Recording starts by specifying
            start and end events in the
            <code class="literal">null_audit_event_record_def</code> variable:
          </p><pre class="programlisting">
SET null_audit_event_record_def =
    'MYSQL_AUDIT_COMMAND_START;MYSQL_AUDIT_COMMAND_END';
</pre><p>
            Statement execution results in storing the events that occur
            in the <code class="literal">null_audit_event_record</code> variable.
          </p><p>
            To disable the plugin after testing it, use this statement
            to unload it:
          </p><pre class="programlisting">
UNINSTALL PLUGIN NULL_AUDIT;
</pre>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="writing-authentication-plugins"></a>28.2.4.9 Writing Authentication Plugins</h4>

</div>

</div>

</div>
<p>
          MySQL supports pluggable authentication, in which plugins are
          invoked to authenticate client connections. Authentication
          plugins enable the use of authentication methods other than
          the built-in method of passwords stored in the
          <code class="literal">mysql.user</code> table. For example, plugins can
          be written to access external authentication methods. Also,
          authentication plugins can support the proxy user capability,
          such that the connecting user is a proxy for another user and
          is treated, for purposes of access control, as having the
          privileges of a different user. For more information, see
          <a class="xref" href="security.html#pluggable-authentication" title="6.3.10 Pluggable Authentication">Section 6.3.10, “Pluggable Authentication”</a>, and
          <a class="xref" href="security.html#proxy-users" title="6.3.11 Proxy Users">Section 6.3.11, “Proxy Users”</a>.
        </p><p>
          An authentication plugin can be written for the server side or
          the client side. Server-side plugins use the same plugin API
          that is used for the other server plugin types such as
          full-text parser or audit plugins (although with a different
          type-specific descriptor). Client-side plugins use the client
          plugin API.
        </p><p>
          Several header files contain information relevant to
          authentication plugins:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              <code class="filename">plugin.h</code>: Defines the
              <code class="literal">MYSQL_AUTHENTICATION_PLUGIN</code> server
              plugin type.
            </p></li><li class="listitem"><p>
              <code class="filename">client_plugin.h</code>: Defines the API for
              client plugins. This includes the client plugin descriptor
              and function prototypes for client plugin C API calls (see
              <a class="xref" href="connectors-apis.html#c-api-plugin-functions" title="27.7.13 C API Client Plugin Functions">Section 27.7.13, “C API Client Plugin Functions”</a>).
            </p></li><li class="listitem"><p>
              <code class="filename">plugin_auth.h</code>: Defines the part of
              the server plugin API specific to authentication plugins.
              This includes the type-specific descriptor for server-side
              authentication plugins and the
              <code class="literal">MYSQL_SERVER_AUTH_INFO</code> structure.
            </p></li><li class="listitem"><p>
              <code class="filename">plugin_auth_common.h</code>: Contains common
              elements of client and server authentication plugins. This
              includes return value definitions and the
              <code class="literal">MYSQL_PLUGIN_VIO</code> structure.
</p></li></ul>
</div>
<p>
          To write an authentication plugin, include the following
          header files in the plugin source file. Other MySQL or general
          header files might also be needed, depending on the plugin
          capabilities and requirements.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              For a source file that implements a server authentication
              plugin, include this file:
            </p><pre class="programlisting">
#include &lt;mysql/plugin_auth.h&gt;
</pre></li><li class="listitem"><p>
              For a source file that implements a client authentication
              plugin, or both client and server plugins, include these
              files:
            </p><pre class="programlisting">
#include &lt;mysql/plugin_auth.h&gt;
#include &lt;mysql/client_plugin.h&gt;
#include &lt;mysql.h&gt;
</pre></li></ul>
</div>
<p>
          <code class="filename">plugin_auth.h</code> includes
          <code class="filename">plugin.h</code> and
          <code class="filename">plugin_auth_common.h</code>, so you need not
          include the latter files explicitly.
        </p><p>
          This section describes how to write a pair of simple server
          and client authentication plugins that work together.
</p>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
            These plugins accept any non-empty password and the password
            is sent in clear text. This is insecure, so the plugins
            <span class="emphasis"><em>should not be used in production
            environments.</em></span>
</p>
</div>
<p>
          The server-side and client-side plugins developed here both
          are named <code class="literal">auth_simple</code>. As described in
          <a class="xref" href="extending-mysql.html#plugin-data-structures" title="28.2.4.2 Plugin Data Structures">Section 28.2.4.2, “Plugin Data Structures”</a>, the plugin library
          file must have the same base name as the client plugin, so the
          source file name is <code class="filename">auth_simple.c</code> and
          produces a library named <code class="filename">auth_simple.so</code>
          (assuming that your system uses <code class="filename">.so</code> as
          the suffix for library files).
        </p><p>
          In MySQL source distributions, authentication plugin source is
          located in the <code class="filename">plugin/auth</code> directory and
          can be examined as a guide to writing other authentication
          plugins. Also, to see how the built-in authentication plugins
          are implemented, see <code class="filename">sql/sql_acl.cc</code> for
          plugins that are built in to the MySQL server and
          <code class="filename">sql-common/client.c</code> for plugins that are
          built in to the <code class="literal">libmysqlclient</code> client
          library. (For the built-in client plugins, note that the
          <code class="literal">auth_plugin_t</code> structures used there differ
          from the structures used with the usual client plugin
          declaration macros. In particular, the first two members are
          provided explicitly, not by declaration macros.)
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="writing-authentication-plugins-server-side"></a>28.2.4.9.1 Writing the Server-Side Authentication Plugin</h5>
</div>
</div>
</div>
<p>
            Declare the server-side plugin with the usual general
            descriptor format that is used for all server plugin types
            (see <a class="xref" href="extending-mysql.html#server-plugin-descriptors" title="28.2.4.2.1 Server Plugin Library and Plugin Descriptors">Section 28.2.4.2.1, “Server Plugin Library and Plugin Descriptors”</a>). For the
            <code class="literal">auth_simple</code> plugin, the descriptor looks
            like this:
          </p><pre class="programlisting">
mysql_declare_plugin(auth_simple)
{
  MYSQL_AUTHENTICATION_PLUGIN,
  &amp;auth_simple_handler,                 /* type-specific descriptor */
  "auth_simple",                        /* plugin name */
  "Author Name",                        /* author */
  "Any-password authentication plugin", /* description */
  PLUGIN_LICENSE_GPL,                   /* license type */
  NULL,                                 /* no init function */
  NULL,                                 /* no deinit function */
  0x0100,                               /* version = 1.0 */
  NULL,                                 /* no status variables */
  NULL,                                 /* no system variables */
  NULL,                                 /* no reserved information */
  0                                     /* no flags */
}
mysql_declare_plugin_end;
</pre><p>
            The <code class="literal">name</code> member
            (<code class="literal">auth_simple</code>) indicates the name to use
            for references to the plugin in statements such as
            <a class="link" href="sql-syntax.html#install-plugin" title="13.7.4.4 INSTALL PLUGIN Syntax"><code class="literal">INSTALL PLUGIN</code></a> or
            <a class="link" href="sql-syntax.html#uninstall-plugin" title="13.7.4.6 UNINSTALL PLUGIN Syntax"><code class="literal">UNINSTALL PLUGIN</code></a>. This is
            also the name displayed by <a class="link" href="sql-syntax.html#show-plugins" title="13.7.6.25 SHOW PLUGINS Syntax"><code class="literal">SHOW
            PLUGINS</code></a> or
            <a class="link" href="information-schema.html#plugins-table" title="24.15 The INFORMATION_SCHEMA PLUGINS Table"><code class="literal">INFORMATION_SCHEMA.PLUGINS</code></a>.
          </p><p>
            The <code class="literal">auth_simple_handler</code> member of the
            general descriptor points to the type-specific descriptor.
            For an authentication plugin, the type-specific descriptor
            is an instance of the <code class="literal">st_mysql_auth</code>
            structure (defined in <code class="filename">plugin_auth.h</code>):
          </p><pre class="programlisting">
struct st_mysql_auth
{
  int interface_version;
  const char *client_auth_plugin;
  int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info);
  int (*generate_authentication_string)(char *outbuf,
      unsigned int *outbuflen, const char *inbuf, unsigned int inbuflen);
  int (*validate_authentication_string)(char* const inbuf, unsigned int buflen);
  int (*set_salt)(const char *password, unsigned int password_len,
                  unsigned char* salt, unsigned char *salt_len);
  const unsigned long authentication_flags;
};
</pre><p>
            The <code class="literal">st_mysql_auth</code> structure has these
            members:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                <code class="literal">interface_version</code>: The type-specific
                API version number, always
                <code class="literal">MYSQL_AUTHENTICATION_INTERFACE_VERSION</code>
              </p></li><li class="listitem"><p>
                <code class="literal">client_auth_plugin</code>: The client plugin
                name
              </p></li><li class="listitem"><p>
                <code class="literal">authenticate_user</code>: A pointer to the
                main plugin function that communicates with the client
              </p></li><li class="listitem"><p>
                <code class="literal">generate_authentication_string</code>: A
                pointer to a plugin function that generates a password
                digest from an authentication string
              </p></li><li class="listitem"><p>
                <code class="literal">validate_authentication_string</code>: A
                pointer to a plugin function that validates a password
                digest
              </p></li><li class="listitem"><p>
                <code class="literal">set_salt</code>: A pointer to a plugin
                function that converts a scrambled password to binary
                form
              </p></li><li class="listitem"><p>
                <code class="literal">authentication_flags</code>: A flags word
</p></li></ul>
</div>
<p>
            The <code class="literal">client_auth_plugin</code> member should
            indicate the name of the client plugin if a specific plugin
            is required. A value of <code class="literal">NULL</code> means
            <span class="quote">“<span class="quote">any plugin.</span>”</span> In the latter case, whatever
            plugin the client uses will do. This is useful if the server
            plugin does not care about the client plugin or what user
            name or password it sends. For example, this might be true
            if the server plugin authenticates only local clients and
            uses some property of the operating system rather than the
            information sent by the client plugin.
          </p><p>
            For <code class="literal">auth_simple</code>, the type-specific
            descriptor looks like this:
          </p><pre class="programlisting">
static struct st_mysql_auth auth_simple_handler =
{
  MYSQL_AUTHENTICATION_INTERFACE_VERSION,
  "auth_simple",             /* required client-side plugin name */
  auth_simple_server         /* server-side plugin main function */
  generate_auth_string_hash, /* generate digest from password string */
  validate_auth_string_hash, /* validate password digest */
  set_salt,                  /* generate password salt value */
  AUTH_FLAG_PRIVILEGED_USER_FOR_PASSWORD_CHANGE
};
</pre><p>
            The main function, <code class="literal">auth_simple_server()</code>,
            takes two arguments representing an I/O structure and a
            <code class="literal">MYSQL_SERVER_AUTH_INFO</code> structure. The
            structure definition, found in
            <code class="filename">plugin_auth.h</code>, looks like this:
          </p><a class="indexterm" name="idm139899455329168"></a><pre class="programlisting">
typedef struct st_mysql_server_auth_info
{
  char *user_name;
  unsigned int user_name_length;
  const char *auth_string;
  unsigned long auth_string_length;
  char authenticated_as[MYSQL_USERNAME_LENGTH+1];
  char external_user[512];
  int  password_used;
  const char *host_or_ip;
  unsigned int host_or_ip_length;
} MYSQL_SERVER_AUTH_INFO;
</pre><p>
            The character set for string members is UTF-8. If there is a
            <code class="literal">_length</code> member associated with a string,
            it indicates the string length in bytes. Strings are also
            null-terminated.
          </p><p>
            When an authentication plugin is invoked by the server, it
            should interpret the
            <code class="literal">MYSQL_SERVER_AUTH_INFO</code> structure members
            as follows. Some of these are used to set the value of SQL
            functions or system variables within the client session, as
            indicated.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                <code class="literal">user_name</code>: The user name sent by the
                client. The value becomes the
                <a class="link" href="functions.html#function_user"><code class="literal">USER()</code></a> function value.
              </p></li><li class="listitem"><p>
                <code class="literal">user_name_length</code>: The length of
                <code class="literal">user_name</code> in bytes.
              </p></li><li class="listitem"><p>
                <code class="literal">auth_string</code>: The value of the
                <code class="literal">authentication_string</code> column of the
                <code class="literal">mysql.user</code> table row for the matching
                account name (that is, the row that matches the client
                user name and host name and that the server uses to
                determine how to authenticate the client).
              </p><p>
                Suppose that you create an account using the following
                statement:
              </p><pre class="programlisting">
CREATE USER 'my_user'@'localhost'
  IDENTIFIED WITH my_plugin AS 'my_auth_string';
</pre><p>
                When <code class="literal">my_user</code> connects from the local
                host, the server invokes <code class="literal">my_plugin</code>
                and passes <code class="literal">'my_auth_string'</code> to it as
                the <code class="literal">auth_string</code> value.
              </p></li><li class="listitem"><p>
                <code class="literal">auth_string_length</code>: The length of
                <code class="literal">auth_string</code> in bytes.
              </p></li><li class="listitem"><p>
                <code class="literal">authenticated_as</code>: The server sets
                this to the user name (the value of
                <code class="literal">user_name</code>). The plugin can alter it
                to indicate that the client should have the privileges
                of a different user. For example, if the plugin supports
                proxy users, the initial value is the name of the
                connecting (proxy) user, and the plugin can change this
                member to the proxied user name. The server then treats
                the proxy user as having the privileges of the proxied
                user (assuming that the other conditions for proxy user
                support are satisfied; see
                <a class="xref" href="extending-mysql.html#writing-authentication-plugins-proxy-users" title="28.2.4.9.4 Implementing Proxy User Support in Authentication Plugins">Section 28.2.4.9.4, “Implementing Proxy User Support in Authentication Plugins”</a>).
                The value is represented as a string at most
                <code class="literal">MYSQL_USER_NAME_LENGTH</code> bytes long,
                plus a terminating null. The value becomes the
                <a class="link" href="functions.html#function_current-user"><code class="literal">CURRENT_USER()</code></a> function
                value.
              </p></li><li class="listitem"><p>
                <code class="literal">external_user</code>: The server sets this
                to the empty string (null terminated). Its value becomes
                the <a class="link" href="server-administration.html#sysvar_external_user"><code class="literal">external_user</code></a>
                system variable value. If the plugin wants that system
                variable to have a different value, it should set this
                member accordingly; for example, to the connecting user
                name. The value is represented as a string at most 511
                bytes long, plus a terminating null.
              </p></li><li class="listitem"><p>
                <code class="literal">password_used</code>: This member applies
                when authentication fails. The plugin can set it or
                ignore it. The value is used to construct the failure
                error message of <code class="literal">Authentication fails. Password
                used: %s</code>. The value of
                <code class="literal">password_used</code> determines how
                <code class="literal">%s</code> is handled, as shown in the
                following table.
</p>
<div class="informaltable">
<a name="mysql-server-auth-info-password-used-member"></a><table summary="Values for the password_used member and how values are handled in the construction of Authentication fails. Password used: %s messages."><col width="25%"><col width="75%"><thead><tr>
                    <th scope="col"><code class="literal">password_used</code></th>
                    <th scope="col"><code class="literal">%s</code> Handling</th>
                  </tr></thead><tbody><tr>
                    <td scope="row">0</td>
                    <td>NO</td>
                  </tr><tr>
                    <td scope="row">1</td>
                    <td>YES</td>
                  </tr><tr>
                    <td scope="row">2</td>
                    <td>There will be no <code class="literal">%s</code></td>
</tr></tbody></table>
</div>
</li><li class="listitem"><p>
                <code class="literal">host_or_ip</code>: The name of the client
                host if it can be resolved, or the IP address otherwise.
              </p></li><li class="listitem"><p>
                <code class="literal">host_or_ip_length</code>: The length of
                <code class="literal">host_or_ip</code> in bytes.
</p></li></ul>
</div>
<p>
            The <code class="literal">auth_simple</code> main function,
            <code class="literal">auth_simple_server()</code>, reads the password
            (a null-terminated string) from the client and succeeds if
            the password is nonempty (first byte not null):
          </p><pre class="programlisting">
static int auth_simple_server (MYSQL_PLUGIN_VIO *vio,
                               MYSQL_SERVER_AUTH_INFO *info)
{
  unsigned char *pkt;
  int pkt_len;

  /* read the password as null-terminated string, fail on error */
  if ((pkt_len= vio-&gt;read_packet(vio, &amp;pkt)) &lt; 0)
    return CR_ERROR;

  /* fail on empty password */
  if (!pkt_len || *pkt == '\0')
  {
    info-&gt;password_used= PASSWORD_USED_NO;
    return CR_ERROR;
  }

  /* accept any nonempty password */
  info-&gt;password_used= PASSWORD_USED_YES;

  return CR_OK;
}
</pre><p>
            The main function should return one of the error codes shown
            in the following table.
</p>
<div class="informaltable">
<a name="auth-simple-server-error-codes"></a><table summary="Error codes for the auth_simple main function, auth_simple_server(), and the meaning of each error code."><col width="40%"><col width="60%"><thead><tr>
                <th scope="col">Error Code</th>
                <th scope="col">Meaning</th>
              </tr></thead><tbody><tr>
                <td scope="row"><code class="literal">CR_OK</code></td>
                <td>Success</td>
              </tr><tr>
                <td scope="row"><code class="literal">CR_OK_HANDSHAKE_COMPLETE</code></td>
                <td>Do not send a status packet back to client</td>
              </tr><tr>
                <td scope="row"><code class="literal">CR_ERROR</code></td>
                <td>Error</td>
              </tr><tr>
                <td scope="row"><code class="literal">CR_AUTH_USER_CREDENTIALS</code></td>
                <td>Authentication failure</td>
              </tr><tr>
                <td scope="row"><code class="literal">CR_AUTH_HANDSHAKE</code></td>
                <td>Authentication handshake failure</td>
              </tr><tr>
                <td scope="row"><code class="literal">CR_AUTH_PLUGIN_ERROR</code></td>
                <td>Internal plugin error</td>
</tr></tbody></table>
</div>
<p>
            For an example of how the handshake works, see the
            <code class="filename">plugin/auth/dialog.c</code> source file.
          </p><p>
            The server counts plugin errors in the Performance Schema
            <a class="link" href="performance-schema.html#host-cache-table" title="25.11.16.1 The host_cache Table"><code class="literal">host_cache</code></a> table.
          </p><p>
            <code class="literal">auth_simple_server()</code> is so basic that it
            does not use the authentication information structure except
            to set the member that indicates whether a password was
            received.
          </p><p>
            A plugin that supports proxy users must return to the server
            the name of the proxied user (the MySQL user whose
            privileges the client user should get). To do this, the
            plugin must set the
            <code class="literal">info-&gt;authenticated_as</code> member to the
            proxied user name. For information about proxying, see
            <a class="xref" href="security.html#proxy-users" title="6.3.11 Proxy Users">Section 6.3.11, “Proxy Users”</a>, and
            <a class="xref" href="extending-mysql.html#writing-authentication-plugins-proxy-users" title="28.2.4.9.4 Implementing Proxy User Support in Authentication Plugins">Section 28.2.4.9.4, “Implementing Proxy User Support in Authentication Plugins”</a>.
          </p><p>
            The <code class="literal">generate_authentication_string</code> member
            of the plugin descriptor takes the password and generates a
            password hash (digest) from it:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                The first two arguments are pointers to the output
                buffer and its maximum length in bytes. The function
                should write the password hash to the output buffer and
                reset the length to the actual hash length.
              </p></li><li class="listitem"><p>
                The second two arguments indicate the password input
                buffer and its length in bytes.
              </p></li><li class="listitem"><p>
                The function returns 0 for success, 1 if an error
                occurred.
</p></li></ul>
</div>
<p>
            For the <code class="literal">auth_simple</code> plugin, the
            <code class="literal">generate_auth_string_hash()</code> function
            implements the
            <code class="literal">generate_authentication_string</code> member. It
            just makes a copy of the password, unless it is too long to
            fit in the output buffer.
          </p><pre class="programlisting">
int generate_auth_string_hash(char *outbuf, unsigned int *buflen,
                              const char *inbuf, unsigned int inbuflen)
{
  /*
    fail if buffer specified by server cannot be copied to output buffer
  */
  if (*buflen &lt; inbuflen)
    return 1;   /* error */
  strncpy(outbuf, inbuf, inbuflen);
  *buflen= strlen(inbuf);
  return 0;     /* success */
}
</pre><p>
            The <code class="literal">validate_authentication_string</code> member
            of the plugin descriptor validates a password hash:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                The arguments are a pointer to the password hash and its
                length in bytes.
              </p></li><li class="listitem"><p>
                The function returns 0 for success, 1 if the password
                hash cannot be validated.
</p></li></ul>
</div>
<p>
            For the <code class="literal">auth_simple</code> plugin, the
            <code class="literal">validate_auth_string_hash()</code> function
            implements the
            <code class="literal">validate_authentication_string</code> member. It
            returns success unconditionally:
          </p><pre class="programlisting">
int validate_auth_string_hash(char* const inbuf  __attribute__((unused)),
                              unsigned int buflen  __attribute__((unused)))
{
  return 0;     /* success */
}

</pre><p>
            The <code class="literal">set_salt</code> member of the plugin
            descriptor is used only by the
            <code class="literal">mysql_native_password</code> plugin (see
            <a class="xref" href="security.html#native-pluggable-authentication" title="6.5.1.1 Native Pluggable Authentication">Section 6.5.1.1, “Native Pluggable Authentication”</a>). For
            other authentication plugins, you can use this trivial
            implementation:
          </p><pre class="programlisting">
int set_salt(const char* password __attribute__((unused)),
             unsigned int password_len __attribute__((unused)),
             unsigned char* salt __attribute__((unused)),
             unsigned char* salt_len)
{
  *salt_len= 0;
  return 0;     /* success */
}
</pre><p>
            The <code class="literal">authentication_flags</code> member of the
            plugin descriptor contains flags that affect plugin
            operation. The permitted flags are:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                <code class="literal">AUTH_FLAG_PRIVILEGED_USER_FOR_PASSWORD_CHANGE</code>:
                Credential changes are a privileged operation. If this
                flag is set, the server requires that the user has the
                global <a class="link" href="security.html#priv_create-user"><code class="literal">CREATE USER</code></a>
                privilege or the <a class="link" href="security.html#priv_update"><code class="literal">UPDATE</code></a>
                privilege for the <code class="literal">mysql</code> database.
              </p></li><li class="listitem"><p>
                <code class="literal">AUTH_FLAG_USES_INTERNAL_STORAGE</code>:
                Whether the plugin uses internal storage (in the
                <code class="literal">authentication_string</code> column of
                <code class="literal">mysql.user</code> rows). If this flag is not
                set, attempts to set the password fail and the server
                produces a warning.
</p></li></ul>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="writing-authentication-plugins-client-side"></a>28.2.4.9.2 Writing the Client-Side Authentication Plugin</h5>

</div>

</div>

</div>
<p>
            Declare the client-side plugin descriptor with the
            <code class="literal">mysql_declare_client_plugin()</code> and
            <code class="literal">mysql_end_client_plugin</code> macros (see
            <a class="xref" href="extending-mysql.html#client-plugin-descriptors" title="28.2.4.2.3 Client Plugin Descriptors">Section 28.2.4.2.3, “Client Plugin Descriptors”</a>). For the
            <code class="literal">auth_simple</code> plugin, the descriptor looks
            like this:
          </p><pre class="programlisting">
mysql_declare_client_plugin(AUTHENTICATION)
  "auth_simple",                        /* plugin name */
  "Author Name",                        /* author */
  "Any-password authentication plugin", /* description */
  {1,0,0},                              /* version = 1.0.0 */
  "GPL",                                /* license type */
  NULL,                                 /* for internal use */
  NULL,                                 /* no init function */
  NULL,                                 /* no deinit function */
  NULL,                                 /* no option-handling function */
  auth_simple_client                    /* main function */
mysql_end_client_plugin;
</pre><p>
            The descriptor members from the plugin name through the
            option-handling function are common to all client plugin
            types. (For descriptions, see
            <a class="xref" href="extending-mysql.html#client-plugin-descriptors" title="28.2.4.2.3 Client Plugin Descriptors">Section 28.2.4.2.3, “Client Plugin Descriptors”</a>.) Following the
            common members, the descriptor has an additional member
            specific to authentication plugins. This is the
            <span class="quote">“<span class="quote">main</span>”</span> function, which handles communication
            with the server. The function takes two arguments
            representing an I/O structure and a connection handler. For
            our simple any-password plugin, the main function does
            nothing but write to the server the password provided by the
            user:
          </p><pre class="programlisting">
static int auth_simple_client (MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
{
  int res;

  /* send password as null-terminated string in clear text */
  res= vio-&gt;write_packet(vio, (const unsigned char *) mysql-&gt;passwd,
                         strlen(mysql-&gt;passwd) + 1);

  return res ? CR_ERROR : CR_OK;
}
</pre><p>
            The main function should return one of the error codes shown
            in the following table.
</p>
<div class="informaltable">
<a name="auth-simple-client-error-codes"></a><table summary="Error codes for the authentication main function and the meaning of each function."><col width="40%"><col width="60%"><thead><tr>
                <th scope="col">Error Code</th>
                <th scope="col">Meaning</th>
              </tr></thead><tbody><tr>
                <td scope="row"><code class="literal">CR_OK</code></td>
                <td>Success</td>
              </tr><tr>
                <td scope="row"><code class="literal">CR_OK_HANDSHAKE_COMPLETE</code></td>
                <td>Success, client done</td>
              </tr><tr>
                <td scope="row"><code class="literal">CR_ERROR</code></td>
                <td>Error</td>
</tr></tbody></table>
</div>
<p>
            <code class="literal">CR_OK_HANDSHAKE_COMPLETE</code> indicates that
            the client has done its part successfully and has read the
            last packet. A client plugin may return
            <code class="literal">CR_OK_HANDSHAKE_COMPLETE</code> if the number of
            round trips in the authentication protocol is not known in
            advance and the plugin must read another packet to determine
            whether authentication is finished.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="writing-authentication-plugins-setup"></a>28.2.4.9.3 Using the Authentication Plugins</h5>

</div>

</div>

</div>
<p>
            To compile and install a plugin library file, use the
            instructions in
            <a class="xref" href="extending-mysql.html#compiling-plugin-libraries" title="28.2.4.3 Compiling and Installing Plugin Libraries">Section 28.2.4.3, “Compiling and Installing Plugin Libraries”</a>. To make the
            library file available for use, install it in the plugin
            directory (the directory named by the
            <a class="link" href="server-administration.html#sysvar_plugin_dir"><code class="literal">plugin_dir</code></a> system
            variable).
          </p><p>
            Register the server-side plugin with the server. For
            example, to load the plugin at server startup, use a
            <a class="link" href="server-administration.html#option_mysqld_plugin-load"><code class="option">--plugin-load=auth_simple.so</code></a>
            option (adjust the <code class="filename">.so</code> suffix for your
            platform as necessary).
          </p><p>
            Create a user for whom the server will use the
            <code class="literal">auth_simple</code> plugin for authentication:
          </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>CREATE USER 'x'@'localhost'</code></strong>
    -&gt; <strong class="userinput"><code>IDENTIFIED WITH auth_simple;</code></strong>
</pre><p>
            Use a client program to connect to the server as user
            <code class="literal">x</code>. The server-side
            <code class="literal">auth_simple</code> plugin communicates with the
            client program that it should use the client-side
            <code class="literal">auth_simple</code> plugin, and the latter sends
            the password to the server. The server plugin should reject
            connections that send an empty password and accept
            connections that send a nonempty password. Invoke the client
            program each way to verify this:
          </p><pre class="programlisting">
shell&gt; <strong class="userinput"><code>mysql --user=x --skip-password</code></strong>
ERROR 1045 (28000): Access denied for user 'x'@'localhost' (using password: NO)

shell&gt; <strong class="userinput"><code>mysql --user=x --password</code></strong>
Enter password: <strong class="userinput"><code>abc</code></strong>
mysql&gt;
</pre><p>
            Because the server plugin accepts any nonempty password, it
            should be considered insecure. After testing the plugin to
            verify that it works, restart the server without the
            <a class="link" href="server-administration.html#option_mysqld_plugin-load"><code class="option">--plugin-load</code></a> option so as
            not to indavertently leave the server running with an
            insecure authentication plugin loaded. Also, drop the user
            with <a class="link" href="sql-syntax.html#drop-user" title="13.7.1.5 DROP USER Syntax"><code class="literal">DROP USER
            'x'@'localhost'</code></a>.
          </p><p>
            For additional information about loading and using
            authentication plugins, see
            <a class="xref" href="server-administration.html#server-plugin-loading" title="5.6.1 Installing and Uninstalling Plugins">Section 5.6.1, “Installing and Uninstalling Plugins”</a>, and
            <a class="xref" href="security.html#pluggable-authentication" title="6.3.10 Pluggable Authentication">Section 6.3.10, “Pluggable Authentication”</a>.
          </p><p>
            If you are writing a client program that supports the use of
            authentication plugins, normally such a program causes a
            plugin to be loaded by calling
            <a class="link" href="connectors-apis.html#mysql-options" title="27.7.7.50 mysql_options()"><code class="literal">mysql_options()</code></a> to set the
            <code class="literal">MYSQL_DEFAULT_AUTH</code> and
            <code class="literal">MYSQL_PLUGIN_DIR</code> options:
          </p><pre class="programlisting">
char *plugin_dir = "<em class="replaceable"><code>path_to_plugin_dir</code></em>";
char *default_auth = "<em class="replaceable"><code>plugin_name</code></em>";

/* ... process command-line options ... */

mysql_options(&amp;mysql, MYSQL_PLUGIN_DIR, plugin_dir);
mysql_options(&amp;mysql, MYSQL_DEFAULT_AUTH, default_auth);
</pre><p>
            Typically, the program will also accept
            <code class="option">--plugin-dir</code> and
            <code class="option">--default-auth</code> options that enable users to
            override the default values.
          </p><p>
            Should a client program require lower-level plugin
            management, the client library contains functions that take
            an <code class="literal">st_mysql_client_plugin</code> argument. See
            <a class="xref" href="connectors-apis.html#c-api-plugin-functions" title="27.7.13 C API Client Plugin Functions">Section 27.7.13, “C API Client Plugin Functions”</a>.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="writing-authentication-plugins-proxy-users"></a>28.2.4.9.4 Implementing Proxy User Support in Authentication Plugins</h5>

</div>

</div>

</div>
<p>
            One of the capabilities that pluggable authentication makes
            possible is proxy users (see <a class="xref" href="security.html#proxy-users" title="6.3.11 Proxy Users">Section 6.3.11, “Proxy Users”</a>).
            For a server-side authentication plugin to participate in
            proxy user support, these conditions must be satisfied:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                When a connecting client should be treated as a proxy
                user, the plugin must return a different name in the
                <code class="literal">authenticated_as</code> member of the
                <code class="literal">MYSQL_SERVER_AUTH_INFO</code> structure, to
                indicate the proxied user name. It may also optionally
                set the <code class="literal">external_user</code> member, to set
                the value of the
                <a class="link" href="server-administration.html#sysvar_external_user"><code class="literal">external_user</code></a> system
                variable.
              </p></li><li class="listitem"><p>
                Proxy user accounts must be set up to be authenticated
                by the plugin. Use the <a class="link" href="sql-syntax.html#create-user" title="13.7.1.3 CREATE USER Syntax"><code class="literal">CREATE
                USER</code></a> or <a class="link" href="sql-syntax.html#grant" title="13.7.1.6 GRANT Syntax"><code class="literal">GRANT</code></a>
                statement to associate accounts with plugins.
              </p></li><li class="listitem"><p>
                Proxy user accounts must have the
                <a class="link" href="security.html#priv_proxy"><code class="literal">PROXY</code></a> privilege for the
                proxied accounts. Use the
                <a class="link" href="sql-syntax.html#grant" title="13.7.1.6 GRANT Syntax"><code class="literal">GRANT</code></a> statement to grant
                this privilege.
</p></li></ul>
</div>
<p>
            In other words, the only aspect of proxy user support
            required of the plugin is that it set
            <code class="literal">authenticated_as</code> to the proxied user
            name. The rest is optional (setting
            <code class="literal">external_user</code>) or done by the DBA using
            SQL statements.
          </p><p>
            How does an authentication plugin determine which proxied
            user to return when the proxy user connects? That depends on
            the plugin. Typically, the plugin maps clients to proxied
            users based on the authentication string passed to it by the
            server. This string comes from the <code class="literal">AS</code>
            part of the <code class="literal">IDENTIFIED WITH</code> clause of the
            <a class="link" href="sql-syntax.html#create-user" title="13.7.1.3 CREATE USER Syntax"><code class="literal">CREATE USER</code></a> statement that
            specifies use of the plugin for authentication.
          </p><p>
            The plugin developer determines the syntax rules for the
            authentication string and implements the plugin according to
            those rules. Suppose that a plugin takes a comma-separated
            list of pairs that map external users to MySQL users. For
            example:
          </p><pre class="programlisting">
CREATE USER ''@'%.example.com'
  IDENTIFIED WITH my_plugin AS 'extuser1=mysqlusera, extuser2=mysqluserb'
CREATE USER ''@'%.example.org'
  IDENTIFIED WITH my_plugin AS 'extuser1=mysqluserc, extuser2=mysqluserd'
</pre><p>
            When the server invokes a plugin to authenticate a client,
            it passes the appropriate authentication string to the
            plugin. The plugin is responsible to:
</p>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
                Parse the string into its components to determine the
                mapping to use
              </p></li><li class="listitem"><p>
                Compare the client user name to the mapping
              </p></li><li class="listitem"><p>
                Return the proper MySQL user name
</p></li></ol>
</div>
<p>
            For example, if <code class="literal">extuser2</code> connects from an
            <code class="literal">example.com</code> host, the server passes
            <code class="literal">'extuser1=mysqlusera,
            extuser2=mysqluserb'</code> to the plugin, and the plugin
            should copy <code class="literal">mysqluserb</code> into
            <code class="literal">authenticated_as</code>, with a terminating null
            byte. If <code class="literal">extuser2</code> connects from an
            <code class="literal">example.org</code> host, the server passes
            <code class="literal">'extuser1=mysqluserc,
            extuser2=mysqluserd'</code>, and the plugin should copy
            <code class="literal">mysqluserd</code> instead.
          </p><p>
            If there is no match in the mapping, the action depends on
            the plugin. If a match is required, the plugin likely will
            return an error. Or the plugin might simply return the
            client name; in this case, it should not change
            <code class="literal">authenticated_as</code>, and the server will not
            treat the client as a proxy.
          </p><p>
            The following example demonstrates how to handle proxy users
            using a plugin named <code class="literal">auth_simple_proxy</code>.
            Like the <code class="literal">auth_simple</code> plugin described
            earlier, <code class="literal">auth_simple_proxy</code> accepts any
            nonempty password as valid (and thus should not be used in
            production environments). In addition, it examines the
            <code class="literal">auth_string</code> authentication string member
            and uses these very simple rules for interpreting it:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                If the string is empty, the plugin returns the user name
                as given and no proxying occurs. That is, the plugin
                leaves the value of <code class="literal">authenticated_as</code>
                unchanged.
              </p></li><li class="listitem"><p>
                If the string is nonempty, the plugin treats it as the
                name of the proxied user and copies it to
                <code class="literal">authenticated_as</code> so that proxying
                occurs.
</p></li></ul>
</div>
<p>
            For testing, set up one account that is not proxied
            according to the preceding rules, and one that is. This
            means that one account has no <code class="literal">AS</code> clause,
            and one includes an <code class="literal">AS</code> clause that names
            the proxied user:
          </p><pre class="programlisting">
CREATE USER 'plugin_user1'@'localhost'
  IDENTIFIED WITH auth_simple_proxy;
CREATE USER 'plugin_user2'@'localhost'
  IDENTIFIED WITH auth_simple_proxy AS 'proxied_user';
</pre><p>
            In addition, create an account for the proxied user and
            grant <code class="literal">plugin_user2</code> the
            <a class="link" href="security.html#priv_proxy"><code class="literal">PROXY</code></a> privilege for it:
          </p><pre class="programlisting">
CREATE USER 'proxied_user'@'localhost'
  IDENTIFIED BY 'proxied_user_pass';
GRANT PROXY
  ON 'proxied_user'@'localhost'
  TO 'plugin_user2'@'localhost';
</pre><p>
            Before the server invokes an authentication plugin, it sets
            <code class="literal">authenticated_as</code> to the client user name.
            To indicate that the user is a proxy, the plugin should set
            <code class="literal">authenticated_as</code> to the proxied user
            name. For <code class="literal">auth_simple_proxy</code>, this means
            that it must examine the <code class="literal">auth_string</code>
            value, and, if the value is nonempty, copy it to the
            <code class="literal">authenticated_as</code> member to return it as
            the name of the proxied user. In addition, when proxying
            occurs, the plugin sets the <code class="literal">external_user</code>
            member to the client user name; this becomes the value of
            the <a class="link" href="server-administration.html#sysvar_external_user"><code class="literal">external_user</code></a> system
            variable.
          </p><pre class="programlisting">
static int auth_simple_proxy_server (MYSQL_PLUGIN_VIO *vio,
                                     MYSQL_SERVER_AUTH_INFO *info)
{
  unsigned char *pkt;
  int pkt_len;

  /* read the password as null-terminated string, fail on error */
  if ((pkt_len= vio-&gt;read_packet(vio, &amp;pkt)) &lt; 0)
    return CR_ERROR;

  /* fail on empty password */
  if (!pkt_len || *pkt == '\0')
  {
    info-&gt;password_used= PASSWORD_USED_NO;
    return CR_ERROR;
  }

  /* accept any nonempty password */
  info-&gt;password_used= PASSWORD_USED_YES;

  /* if authentication string is nonempty, use as proxied user name */
  /* and use client name as external_user value */
  if (info-&gt;auth_string_length &gt; 0)
  {
    strcpy (info-&gt;authenticated_as, info-&gt;auth_string);
    strcpy (info-&gt;external_user, info-&gt;user_name);
  }

  return CR_OK;
}
</pre><p>
            After a successful connection, the
            <a class="link" href="functions.html#function_user"><code class="literal">USER()</code></a> function should
            indicate the connecting client user and host name, and
            <a class="link" href="functions.html#function_current-user"><code class="literal">CURRENT_USER()</code></a> should
            indicate the account whose privileges apply during the
            session. The latter value should be the connecting user
            account if no proxying occurs or the proxied account if
            proxying does occur.
          </p><p>
            Compile and install the plugin, then test it. First, connect
            as <code class="literal">plugin_user1</code>:
          </p><pre class="programlisting">
shell&gt; <strong class="userinput"><code>mysql --user=plugin_user1 --password</code></strong>
Enter password: <strong class="userinput"><code>x</code></strong>
</pre><p>
            In this case, there should be no proxying:
          </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>SELECT USER(), CURRENT_USER(), @@proxy_user, @@external_user\G</code></strong>
*************************** 1. row ***************************
         USER(): plugin_user1@localhost
 CURRENT_USER(): plugin_user1@localhost
   @@proxy_user: NULL
@@external_user: NULL
</pre><p>
            Then connect as <code class="literal">plugin_user2</code>:
          </p><pre class="programlisting">
shell&gt; <strong class="userinput"><code>mysql --user=plugin_user2 --password</code></strong>
Enter password: <strong class="userinput"><code>x</code></strong>
</pre><p>
            In this case, <code class="literal">plugin_user2</code> should be
            proxied to <code class="literal">proxied_user</code>:
          </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>SELECT USER(), CURRENT_USER(), @@proxy_user, @@external_user\G</code></strong>
*************************** 1. row ***************************
         USER(): plugin_user2@localhost
 CURRENT_USER(): proxied_user@localhost
   @@proxy_user: 'plugin_user2'@'localhost'
@@external_user: 'plugin_user2'@'localhost'
</pre>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="writing-password-validation-plugins"></a>28.2.4.10 Writing Password-Validation Plugins</h4>

</div>

</div>

</div>
<p>
          This section describes how to write a server-side
          password-validation plugin. The instructions are based on the
          source code in the
          <code class="literal">plugin/password_validation</code> directory of
          MySQL source distributions. The
          <code class="filename">validate_password.cc</code> source file in that
          directory implements the plugin named
          <code class="literal">validate_password</code>.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
            In MySQL 8.0.4, the <code class="literal">validate_password</code>
            plugin was reimplemented as the
            <code class="literal">validate_password</code> component. The plugin
            form of <code class="literal">validate_password</code> is still
            available but is now deprecated and will be removed in a
            future version of MySQL. MySQL installations that use the
            plugin should make the transition to using the component
            instead. See
            <a class="xref" href="security.html#validate-password-transitioning" title="6.5.3.3 Transitioning to the Password Validation Component">Section 6.5.3.3, “Transitioning to the Password Validation Component”</a>.
</p>
</div>
<p>
          To write a password-validation plugin, include the following
          header file in the plugin source file. Other MySQL or general
          header files might also be needed, depending on the plugin
          capabilities and requirements.
        </p><pre class="programlisting">
#include &lt;mysql/plugin_validate_password.h&gt;
</pre><p>
          <code class="filename">plugin_validate_password.h</code> includes
          <code class="filename">plugin.h</code>, so you need not include the
          latter file explicitly. <code class="filename">plugin.h</code> defines
          the <code class="literal">MYSQL_VALIDATE_PASSWORD_PLUGIN</code> server
          plugin type and the data structures needed to declare the
          plugin. <code class="filename">plugin_validate_password.h</code>
          defines data structures specific to password-validation
          plugins.
        </p><p>
          A password-validation plugin, like any MySQL server plugin,
          has a general plugin descriptor (see
          <a class="xref" href="extending-mysql.html#server-plugin-descriptors" title="28.2.4.2.1 Server Plugin Library and Plugin Descriptors">Section 28.2.4.2.1, “Server Plugin Library and Plugin Descriptors”</a>). In
          <code class="filename">validate_password.cc</code>, the general
          descriptor for <code class="literal">validate_password</code> looks like
          this:
        </p><pre class="programlisting">
mysql_declare_plugin(validate_password)
{
  MYSQL_VALIDATE_PASSWORD_PLUGIN,     /*   type                            */
  &amp;validate_password_descriptor,      /*   descriptor                      */
  "validate_password",                /*   name                            */
  "Oracle Corporation",               /*   author                          */
  "check password strength",          /*   description                     */
  PLUGIN_LICENSE_GPL,
  validate_password_init,             /*   init function (when loaded)     */
  validate_password_deinit,           /*   deinit function (when unloaded) */
  0x0100,                             /*   version                         */
  NULL,
  validate_password_system_variables, /*   system variables                */
  NULL,
  0,
}
mysql_declare_plugin_end;
</pre><p>
          The <code class="literal">name</code> member
          (<code class="literal">validate_password</code>) indicates the name to
          use for references to the plugin in statements such as
          <a class="link" href="sql-syntax.html#install-plugin" title="13.7.4.4 INSTALL PLUGIN Syntax"><code class="literal">INSTALL PLUGIN</code></a> or
          <a class="link" href="sql-syntax.html#uninstall-plugin" title="13.7.4.6 UNINSTALL PLUGIN Syntax"><code class="literal">UNINSTALL PLUGIN</code></a>. This is also
          the name displayed by
          <a class="link" href="information-schema.html#plugins-table" title="24.15 The INFORMATION_SCHEMA PLUGINS Table"><code class="literal">INFORMATION_SCHEMA.PLUGINS</code></a> or
          <a class="link" href="sql-syntax.html#show-plugins" title="13.7.6.25 SHOW PLUGINS Syntax"><code class="literal">SHOW PLUGINS</code></a>.
        </p><p>
          The general descriptor also refers to
          <code class="literal">validate_password_system_variables</code>, a
          structure that exposes several system variables to the
          <a class="link" href="sql-syntax.html#show-variables" title="13.7.6.39 SHOW VARIABLES Syntax"><code class="literal">SHOW VARIABLES</code></a> statement:
        </p><pre class="programlisting">
static struct st_mysql_sys_var* validate_password_system_variables[]= {
  MYSQL_SYSVAR(length),
  MYSQL_SYSVAR(number_count),
  MYSQL_SYSVAR(mixed_case_count),
  MYSQL_SYSVAR(special_char_count),
  MYSQL_SYSVAR(policy),
  MYSQL_SYSVAR(dictionary_file),
  NULL
};
</pre><p>
          The <code class="literal">validate_password_init</code> initialization
          function reads the dictionary file if one was specified, and
          the <code class="literal">validate_password_deinit</code> function frees
          data structures associated with the file.
        </p><p>
          The <code class="literal">validate_password_descriptor</code> value in
          the general descriptor points to the type-specific descriptor.
          For password-validation plugins, this descriptor has the
          following structure:
        </p><pre class="programlisting">
struct st_mysql_validate_password
{
  int interface_version;
  /*
    This function returns TRUE for passwords which satisfy the password
    policy (as chosen by plugin variable) and FALSE for all other
    password
  */
  int (*validate_password)(mysql_string_handle password);
  /*
    This function returns the password strength (0-100) depending
    upon the policies
  */
  int (*get_password_strength)(mysql_string_handle password);
};
</pre><p>
          The type-specific descriptor has these members:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              <code class="literal">interface_version</code>: By convention,
              type-specific plugin descriptors begin with the interface
              version for the given plugin type. The server checks
              <code class="literal">interface_version</code> when it loads the
              plugin to see whether the plugin is compatible with it.
              For password-validation plugins, the value of the
              <code class="literal">interface_version</code> member is
              <code class="literal">MYSQL_VALIDATE_PASSWORD_INTERFACE_VERSION</code>
              (defined in
              <code class="literal">plugin_validate_password.h</code>).
            </p></li><li class="listitem"><p>
              <code class="literal">validate_password</code>: A function that the
              server calls to test whether a password satisfies the
              current password policy. It returns 1 if the password is
              okay and 0 otherwise. The argument is the password, passed
              as a <code class="literal">mysql_string_handle</code> value. This
              data type is implemented by the
              <code class="literal">mysql_string</code> server service. For
              details, see the <code class="filename">string_service.h</code> and
              <code class="filename">string_service.cc</code> source files in the
              <code class="filename">sql</code> directory.
            </p></li><li class="listitem"><p>
              <code class="literal">get_password_strength</code>: A function that
              the server calls to assess the strength of a password. It
              returns a value from 0 (weak) to 100 (strong). The
              argument is the password, passed as a
              <code class="literal">mysql_string_handle</code> value.
</p></li></ul>
</div>
<p>
          For the <code class="literal">validate_password</code> plugin, the
          type-specific descriptor looks like this:
        </p><pre class="programlisting">
static struct st_mysql_validate_password validate_password_descriptor=
{
  MYSQL_VALIDATE_PASSWORD_INTERFACE_VERSION,
  validate_password,                         /* validate function          */
  get_password_strength                      /* validate strength function */
};
</pre><p>
          To compile and install a plugin library file, use the
          instructions in <a class="xref" href="extending-mysql.html#compiling-plugin-libraries" title="28.2.4.3 Compiling and Installing Plugin Libraries">Section 28.2.4.3, “Compiling and Installing Plugin Libraries”</a>.
          To make the library file available for use, install it in the
          plugin directory (the directory named by the
          <a class="link" href="server-administration.html#sysvar_plugin_dir"><code class="literal">plugin_dir</code></a> system variable).
          For the <code class="literal">validate_password</code> plugin, it is
          compiled and installed when you build MySQL from source. It is
          also included in binary distributions. The build process
          produces a shared object library with a name of
          <code class="filename">validate_password.so</code> (the
          <code class="filename">.so</code> suffix might differ depending on your
          platform).
        </p><p>
          To register the plugin at runtime, use this statement (adjust
          the <code class="filename">.so</code> suffix for your platform as
          necessary):
        </p><pre class="programlisting">
INSTALL PLUGIN validate_password SONAME 'validate_password.so';
</pre><p>
          For additional information about plugin loading, see
          <a class="xref" href="server-administration.html#server-plugin-loading" title="5.6.1 Installing and Uninstalling Plugins">Section 5.6.1, “Installing and Uninstalling Plugins”</a>.
        </p><p>
          To verify plugin installation, examine the
          <a class="link" href="information-schema.html#plugins-table" title="24.15 The INFORMATION_SCHEMA PLUGINS Table"><code class="literal">INFORMATION_SCHEMA.PLUGINS</code></a> table
          or use the <a class="link" href="sql-syntax.html#show-plugins" title="13.7.6.25 SHOW PLUGINS Syntax"><code class="literal">SHOW PLUGINS</code></a>
          statement. See <a class="xref" href="server-administration.html#obtaining-plugin-information" title="5.6.2 Obtaining Server Plugin Information">Section 5.6.2, “Obtaining Server Plugin Information”</a>.
        </p><p>
          While the <code class="literal">validate_password</code> plugin is
          installed, it exposes system variables that indicate the
          password-checking parameters:
        </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>SHOW VARIABLES LIKE 'validate_password%';</code></strong>
+--------------------------------------+--------+
| Variable_name                        | Value  |
+--------------------------------------+--------+
| validate_password_dictionary_file    |        |
| validate_password_length             | 8      |
| validate_password_mixed_case_count   | 1      |
| validate_password_number_count       | 1      |
| validate_password_policy             | MEDIUM |
| validate_password_special_char_count | 1      |
+--------------------------------------+--------+
</pre><p>
          For descriptions of these variables, see
          <a class="xref" href="security.html#validate-password-options-variables" title="6.5.3.2 Password Validation Options and Variables">Section 6.5.3.2, “Password Validation Options and Variables”</a>.
        </p><p>
          To disable the plugin after testing it, use this statement to
          unload it:
        </p><pre class="programlisting">
UNINSTALL PLUGIN validate_password;
</pre>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="writing-protocol-trace-plugins"></a>28.2.4.11 Writing Protocol Trace Plugins</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm139899455018736"></a><p>
          MySQL supports the use of protocol trace plugins: client-side
          plugins that implement tracing of communication between a
          client and the server that takes place using the client/server
          protocol.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="test-protocol-trace-plugin"></a>28.2.4.11.1 Using the Test Protocol Trace Plugin</h5>
</div>
</div>
</div>
<a class="indexterm" name="idm139899455015520"></a><a class="indexterm" name="idm139899455014432"></a><p>
            MySQL includes a test protocol trace plugin that serves to
            illustrate the information available from such plugins, and
            as a guide to writing other protocol trace plugins. To see
            how the test plugin works, use a MySQL source distribution;
            binary distributions are built with the test plugin
            disabled.
          </p><p>
            Enable the test protocol trace plugin by configuring MySQL
            with the
            <a class="link" href="installing.html#option_cmake_with_test_trace_plugin"><code class="option">WITH_TEST_TRACE_PLUGIN</code></a>
            <span class="command"><strong>CMake</strong></span> option enabled. This causes the
            test trace plugin to be built and MySQL client programs to
            load it, but the plugin has no effect by default. Control
            the plugin using these environment variables:
</p><a class="indexterm" name="idm139899455009680"></a><a class="indexterm" name="idm139899455008576"></a><a class="indexterm" name="idm139899455007088"></a><a class="indexterm" name="idm139899455005984"></a>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                <code class="literal">MYSQL_TEST_TRACE_DEBUG</code>: Set this
                variable to a value other than 0 to cause the test
                plugin to produce diagnostic output on
                <code class="literal">stderr</code>.
              </p></li><li class="listitem"><p>
                <code class="literal">MYSQL_TEST_TRACE_CRASH</code>: Set this
                variable to a value other than 0 to cause the test
                plugin to abort the client program if it detects an
                invalid trace event.
</p></li></ul>
</div>
<div class="caution" style="margin-left: 0.5in; margin-right: 0.5in;">
<div class="admon-title">
Caution
</div>
<p>
              Diagnostic output from the test protocol trace plugin can
              disclose passwords and other sensitive information.
</p>
</div>
<p>
            Given a MySQL installation built from source with the test
            plugin enabled, you can see a trace of the communication
            between the <a class="link" href="programs.html#mysql" title="4.5.1 mysql — The MySQL Command-Line Tool"><span class="command"><strong>mysql</strong></span></a> client and the MySQL
            server as follows:
          </p><pre class="programlisting">
shell&gt; <strong class="userinput"><code>export MYSQL_TEST_TRACE_DEBUG=1</code></strong>
shqll&gt; <strong class="userinput"><code>mysql</code></strong>
test_trace: Test trace plugin initialized
test_trace: Starting tracing in stage CONNECTING
test_trace: stage: CONNECTING, event: CONNECTING
test_trace: stage: CONNECTING, event: CONNECTED
test_trace: stage: WAIT_FOR_INIT_PACKET, event: READ_PACKET
test_trace: stage: WAIT_FOR_INIT_PACKET, event: PACKET_RECEIVED
test_trace: packet received: 87 bytes
  0A 35 2E 37 2E 33 2D 6D  31 33 2D 64 65 62 75 67   .5.7.3-m13-debug
  2D 6C 6F 67 00 04 00 00  00 2B 7C 4F 55 3F 79 67   -log.....+|OU?yg
test_trace: 004: stage: WAIT_FOR_INIT_PACKET, event: INIT_PACKET_RECEIVED
test_trace: 004: stage: AUTHENTICATE, event: AUTH_PLUGIN
test_trace: 004: Using authentication plugin: mysql_native_password
test_trace: 004: stage: AUTHENTICATE, event: SEND_AUTH_RESPONSE
test_trace: 004: sending packet: 188 bytes
  85 A6 7F 00 00 00 00 01  21 00 00 00 00 00 00 00   .?......!.......
  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
...
mysql&gt; <strong class="userinput"><code>quit</code></strong>
test_trace: 008: stage: READY_FOR_COMMAND, event: SEND_COMMAND
test_trace: 008: QUIT
test_trace: 008: stage: READY_FOR_COMMAND, event: PACKET_SENT
test_trace: 008: packet sent: 0 bytes
test_trace: 008: stage: READY_FOR_COMMAND, event: DISCONNECTED
test_trace: 008: Connection  closed
test_trace: 008: Tracing connection has ended
Bye
test_trace: Test trace plugin de-initialized
</pre><p>
            To disable trace output, do this:
          </p><pre class="programlisting">
shell&gt; <strong class="userinput"><code>MYSQL_TEST_TRACE_DEBUG=</code></strong>
</pre>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="using-own-protocol-trace-plugins"></a>28.2.4.11.2 Using Your Own Protocol Trace Plugins</h5>

</div>

</div>

</div>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
<div class="admon-title">
Note
</div>
<p>
              To use your own protocol trace plugins, you must configure
              MySQL with the
              <a class="link" href="installing.html#option_cmake_with_test_trace_plugin"><code class="option">WITH_TEST_TRACE_PLUGIN</code></a>
              <span class="command"><strong>CMake</strong></span> option
              <span class="emphasis"><em>disabled</em></span> because only one protocol
              trace plugin can be loaded at a time and an error occurs
              for attempts to load a second one. If you have already
              built MySQL with the test protocol trace plugin enabled to
              see how it works, you must rebuild MySQL without it before
              you can use your own plugins.
</p>
</div>
<p>
            This section discusses how to write a basic protocol trace
            plugin named <code class="literal">simple_trace</code>. This plugin
            provides a framework showing how to set up the client plugin
            descriptor and create the trace-related callback functions.
            In <code class="literal">simple_trace</code>, these functions are
            rudimentary and do little other than illustrate the
            arguments required. To see in detail how a trace plugin can
            make use of trace event information, check the source file
            for the test protocol trace plugin
            (<code class="filename">test_trace_plugin.cc</code> in the
            <code class="filename">libmysql</code> directory of a MySQL source
            distribution). However, note that the
            <code class="literal">st_mysql_client_plugin_TRACE</code> structure
            used there differs from the structures used with the usual
            client plugin declaration macros. In particular, the first
            two members are defined explicitly, not implicitly by
            declaration macros.
          </p><p>
            Several header files contain information relevant to
            protocol trace plugins:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                <code class="filename">client_plugin.h</code>: Defines the API
                for client plugins. This includes the client plugin
                descriptor and function prototypes for client plugin C
                API calls (see
                <a class="xref" href="connectors-apis.html#c-api-plugin-functions" title="27.7.13 C API Client Plugin Functions">Section 27.7.13, “C API Client Plugin Functions”</a>).
              </p></li><li class="listitem"><p>
                <code class="filename">plugin_trace.h</code>: Contains
                declarations for client-side plugins of type
                <code class="literal">MYSQL_CLIENT_TRACE_PLUGIN</code>. It also
                contains descriptions of the permitted protocol stages,
                transitions between stages, and the types of events
                permitted at each stage.
</p></li></ul>
</div>
<p>
            To write a protocol trace plugin, include the following
            header files in the plugin source file. Other MySQL or
            general header files might also be needed, depending on the
            plugin capabilities and requirements.
          </p><pre class="programlisting">
#include &lt;mysql/plugin_trace.h&gt;
#include &lt;mysql.h&gt;
</pre><p>
            <code class="filename">plugin_trace.h</code> includes
            <code class="filename">client_plugin.h</code>, so you need not
            include the latter file explicitly.
          </p><p>
            Declare the client-side plugin descriptor with the
            <code class="literal">mysql_declare_client_plugin()</code> and
            <code class="literal">mysql_end_client_plugin</code> macros (see
            <a class="xref" href="extending-mysql.html#client-plugin-descriptors" title="28.2.4.2.3 Client Plugin Descriptors">Section 28.2.4.2.3, “Client Plugin Descriptors”</a>). For the
            <code class="literal">simple_trace</code> plugin, the descriptor looks
            like this:
          </p><pre class="programlisting">
mysql_declare_client_plugin(TRACE)
  "simple_trace",                 /* plugin name */
  "Author Name",                  /* author */
  "Simple protocol trace plugin", /* description */
  {1,0,0},                        /* version = 1.0.0 */
  "GPL",                          /* license type */
  NULL,                           /* for internal use */
  plugin_init,                    /* initialization function */
  plugin_deinit,                  /* deinitialization function */
  plugin_options,                 /* option-handling function */
  trace_start,                    /* start-trace function */
  trace_stop,                     /* stop-trace function */
  trace_event                     /* event-handling function */
mysql_end_client_plugin;
</pre><p>
            The descriptor members from the plugin name through the
            option-handling function are common to all client plugin
            types. The members following the common members implement
            trace event handling.
          </p><p>
            Function members for which the plugin needs no processing
            can be declared as <code class="literal">NULL</code> in the
            descriptor, in which case you need not write any
            corresponding function. For illustration purposes and to
            show the argument syntax, the following discussion
            implements all functions listed in the descriptor, even
            though some of them do nothing,
          </p><p>
            The initialization, deinitialization, and options functions
            common to all client plugins are declared as follows. For a
            description of the arguments and return values, see
            <a class="xref" href="extending-mysql.html#client-plugin-descriptors" title="28.2.4.2.3 Client Plugin Descriptors">Section 28.2.4.2.3, “Client Plugin Descriptors”</a>.
          </p><pre class="programlisting">
static int
plugin_init(char *errbuf, size_t errbuf_len, int argc, va_list args)
{
  return 0;
}

static int
plugin_deinit()
{
  return 0;
}

static int
plugin_options(const char *option, const void *value)
{
  return 0;
}
</pre><p>
            The trace-specific members of the client plugin descriptor
            are callback functions. The following descriptions provide
            more detail on how they are used. Each has a first argument
            that is a pointer to the plugin instance in case your
            implementation needs to access it.
          </p><p>
            <code class="literal">trace_start()</code>: This function is called at
            the start of each traced connection (each connection that
            starts after the plugin is loaded). It is passed the
            connection handler and the protocol stage at which tracing
            starts. <code class="literal">trace_start()</code> allocates memory
            needed by the <code class="literal">trace_event()</code> function, if
            any, and returns a pointer to it. If no memory is needed,
            this function returns <code class="literal">NULL</code>.
          </p><pre class="programlisting">
static void*
trace_start(struct st_mysql_client_plugin_TRACE *self,
            MYSQL *conn,
            enum protocol_stage stage)
{
  struct st_trace_data *plugin_data= malloc(sizeof(struct st_trace_data));

  fprintf(stderr, "Initializing trace: stage %d\n", stage);
  if (plugin_data)
  {
    memset(plugin_data, 0, sizeof(struct st_trace_data));
    fprintf(stderr, "Trace initialized\n");
    return plugin_data;
  }
  fprintf(stderr, "Could not initialize trace\n");
  exit(1);
}
</pre><p>
            <code class="literal">trace_stop()</code>: This function is called
            when tracing of the connection ends. That usually happens
            when the connection is closed, but can happen earlier. For
            example, <code class="literal">trace_event()</code> can return a
            nonzero value at any time and that causes tracing of the
            connection to terminate. <code class="literal">trace_stop()</code> is
            then called even though the connection has not ended.
          </p><p>
            <code class="literal">trace_stop()</code> is passed the connection
            handler and a pointer to the memory allocated by
            <code class="literal">trace_start()</code> (<code class="literal">NULL</code> if
            none). If the pointer is non-<code class="literal">NULL</code>,
            <code class="literal">trace_stop()</code> should deallocate the
            memory. This function returns no value.
          </p><pre class="programlisting">
static void
trace_stop(struct st_mysql_client_plugin_TRACE *self,
           MYSQL *conn,
           void *plugin_data)
{
  fprintf(stderr, "Terminating trace\n");
  if (plugin_data)
    free(plugin_data);
}
</pre><p>
            <code class="literal">trace_event()</code>: This function is called
            for each event occurrence. It is passed a pointer to the
            memory allocated by <code class="literal">trace_start()</code>
            (<code class="literal">NULL</code> if none), the connection handler,
            the current protocol stage and event codes, and event data.
            This function returns 0 to continue tracing, nonzero if
            tracing should stop.
          </p><pre class="programlisting">
static int
trace_event(struct st_mysql_client_plugin_TRACE *self,
            void *plugin_data,
            MYSQL *conn,
            enum protocol_stage stage,
            enum trace_event event,
            struct st_trace_event_args args)
{
  fprintf(stderr, "Trace event received: stage %d, event %d\n", stage, event);
  if (event == TRACE_EVENT_DISCONNECTED)
    fprintf(stderr, "Connection closed\n");
  return 0;
}
</pre><p>
            The tracing framework shuts down tracing of the connection
            when the connection ends, so
            <code class="literal">trace_event()</code> should return nonzero only
            if you want to terminate tracing of the connection early.
            Suppose that you want to trace only connections for a
            certain MySQL account. After authentication, you can check
            the user name for the connection and stop tracing if it is
            not the user in whom you are interested.
          </p><p>
            For each call to <code class="literal">trace_event()</code>, the
            <code class="literal">st_trace_event_args</code> structure contains
            the event data. It has this definition:
          </p><pre class="programlisting">
struct st_trace_event_args
{
  const char           *plugin_name;
  int                   cmd;
  const unsigned char  *hdr;
  size_t                hdr_len;
  const unsigned char  *pkt;
  size_t                pkt_len;
};
</pre><p>
            For different event types, the
            <code class="literal">st_trace_event_args</code> structure contains
            the information described following. All lengths are in
            bytes. Unused members are set to
            <code class="literal">0</code>/<code class="literal">NULL</code>.
          </p><p>
            <code class="literal">AUTH_PLUGIN</code> event:
          </p><pre class="programlisting">
plugin_name  The name of the plugin
</pre><p>
            <code class="literal">SEND_COMMAND</code> event:
          </p><pre class="programlisting">
cmd          The command code
hdr          Pointer to the command packet header
hdr_len      Length of the header
pkt          Pointer to the command arguments
pkt_len      Length of the arguments
</pre><p>
            Other <code class="literal">SEND_<em class="replaceable"><code>xxx</code></em></code>
            and
            <code class="literal"><em class="replaceable"><code>xxx</code></em>_RECEIVED</code>
            events:
          </p><pre class="programlisting">
pkt          Pointer to the data sent or received
pkt_len      Length of the data
</pre><p>
            <code class="literal">PACKET_SENT</code> event:
          </p><pre class="programlisting">
pkt_len      Number of bytes sent
</pre><p>
            To compile and install a plugin library file, use the
            instructions in
            <a class="xref" href="extending-mysql.html#compiling-plugin-libraries" title="28.2.4.3 Compiling and Installing Plugin Libraries">Section 28.2.4.3, “Compiling and Installing Plugin Libraries”</a>. To make the
            library file available for use, install it in the plugin
            directory (the directory named by the
            <a class="link" href="server-administration.html#sysvar_plugin_dir"><code class="literal">plugin_dir</code></a> system
            variable).
          </p><p>
            After the plugin library file is compiled and installed in
            the plugin directory, you can test it easily by setting the
            <code class="literal">LIBMYSQL_PLUGINS</code> environment variable to
            the plugin name, which affects any client program that uses
            that variable. <a class="link" href="programs.html#mysql" title="4.5.1 mysql — The MySQL Command-Line Tool"><span class="command"><strong>mysql</strong></span></a> is one such program:
          </p><pre class="programlisting">
shell&gt; <strong class="userinput"><code>export LIBMYSQL_PLUGINS=simple_trace</code></strong>
shqll&gt; <strong class="userinput"><code>mysql</code></strong>
Initializing trace: stage 0
Trace initialized
Trace event received: stage 0, event 1
Trace event received: stage 0, event 2
...
Welcome to the MySQL monitor.  Commands end with ; or \g.
Trace event received
Trace event received
...
mysql&gt; <strong class="userinput"><code>SELECT 1;</code></strong>
Trace event received: stage 4, event 12
Trace event received: stage 4, event 16
...
Trace event received: stage 8, event 14
Trace event received: stage 8, event 15
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)

mysql&gt; <strong class="userinput"><code>quit</code></strong>
Trace event received: stage 4, event 12
Trace event received: stage 4, event 16
Trace event received: stage 4, event 3
Connection closed
Terminating trace
Bye
</pre><p>
            To stop the trace plugin from being loaded, do this:
          </p><pre class="programlisting">
shell&gt; <strong class="userinput"><code>LIBMYSQL_PLUGINS=</code></strong>
</pre><p>
            It is also possible to write client programs that directly
            load the plugin. You can tell the client where the plugin
            directory is located by calling
            <a class="link" href="connectors-apis.html#mysql-options" title="27.7.7.50 mysql_options()"><code class="literal">mysql_options()</code></a> to set the
            <code class="literal">MYSQL_PLUGIN_DIR</code> option:
          </p><pre class="programlisting">
char *plugin_dir = "<em class="replaceable"><code>path_to_plugin_dir</code></em>";

/* ... process command-line options ... */

mysql_options(&amp;mysql, MYSQL_PLUGIN_DIR, plugin_dir);
</pre><p>
            Typically, the program will also accept a
            <code class="option">--plugin-dir</code> option that enables users to
            override the default value.
          </p><p>
            Should a client program require lower-level plugin
            management, the client library contains functions that take
            an <code class="literal">st_mysql_client_plugin</code> argument. See
            <a class="xref" href="connectors-apis.html#c-api-plugin-functions" title="27.7.13 C API Client Plugin Functions">Section 27.7.13, “C API Client Plugin Functions”</a>.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="writing-keyring-plugins"></a>28.2.4.12 Writing Keyring Plugins</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm139899454907696"></a><a class="indexterm" name="idm139899454906624"></a><p>
          MySQL Server supports a keyring service that enables internal
          server components and plugins to securely store sensitive
          information for later retrieval. This section describes how to
          write a server-side keyring plugin that can be used by service
          functions to perform key-management operations. For general
          keyring information, see <a class="xref" href="security.html#keyring" title="6.5.4 The MySQL Keyring">Section 6.5.4, “The MySQL Keyring”</a>.
        </p><p>
          The instructions here are based on the source code in the
          <code class="literal">plugin/keyring</code> directory of MySQL source
          distributions. The source files in that directory implement a
          plugin named <code class="literal">keyring_file</code> that uses a file
          local to the server host for data storage.
        </p><p>
          To write a keyring plugin, include the following header file
          in the plugin source file. Other MySQL or general header files
          might also be needed, depending on the plugin capabilities and
          requirements.
        </p><pre class="programlisting">
#include &lt;mysql/plugin_keyring.h&gt;
</pre><p>
          <code class="filename">plugin_keyring.h</code> includes
          <code class="filename">plugin.h</code>, so you need not include the
          latter file explicitly. <code class="filename">plugin.h</code> defines
          the <code class="literal">MYSQL_KEYRING_PLUGIN</code> server plugin type
          and the data structures needed to declare the plugin.
          <code class="filename">plugin_keyring.h</code> defines data structures
          specific to keyring plugins.
        </p><p>
          A keyring plugin, like any MySQL server plugin, has a general
          plugin descriptor (see
          <a class="xref" href="extending-mysql.html#server-plugin-descriptors" title="28.2.4.2.1 Server Plugin Library and Plugin Descriptors">Section 28.2.4.2.1, “Server Plugin Library and Plugin Descriptors”</a>). In
          <code class="filename">keyring.cc</code>, the general descriptor for
          <code class="literal">keyring_file</code> looks like this:
        </p><pre class="programlisting">
mysql_declare_plugin(keyring_file)
{
  MYSQL_KEYRING_PLUGIN,     /* type                                     */
  &amp;keyring_descriptor,      /* descriptor                               */
  "keyring_file",           /* name                                     */
  "Oracle Corporation",     /* author                                   */
  "store/fetch authentication data to/from a flat file", /* description */
  PLUGIN_LICENSE_GPL,
  keyring_init,             /* init function (when loaded)              */
  keyring_deinit,           /* deinit function (when unloaded)          */
  0x0100,                   /* version                                  */
  NULL,                     /* status variables                         */
  keyring_system_variables, /* system variables                         */
  NULL,
  0,
}
mysql_declare_plugin_end;
</pre><p>
          The <code class="literal">name</code> member
          (<code class="literal">keyring_file</code>) indicates the plugin name.
          This is the name displayed by
          <a class="link" href="information-schema.html#plugins-table" title="24.15 The INFORMATION_SCHEMA PLUGINS Table"><code class="literal">INFORMATION_SCHEMA.PLUGINS</code></a> or
          <a class="link" href="sql-syntax.html#show-plugins" title="13.7.6.25 SHOW PLUGINS Syntax"><code class="literal">SHOW PLUGINS</code></a>.
        </p><p>
          The general descriptor also refers to
          <code class="literal">keyring_system_variables</code>, a structure that
          exposes a system variable to the <a class="link" href="sql-syntax.html#show-variables" title="13.7.6.39 SHOW VARIABLES Syntax"><code class="literal">SHOW
          VARIABLES</code></a> statement:
        </p><pre class="programlisting">
static struct st_mysql_sys_var *keyring_system_variables[]= {
  MYSQL_SYSVAR(data),
  NULL
};
</pre><p>
          The <code class="literal">keyring_init</code> initialization function
          creates the data file if it does not exist, then reads it and
          initializes the keystore. The
          <code class="literal">keyring_deinit</code> function frees data
          structures associated with the file.
        </p><p>
          The <code class="literal">keyring_descriptor</code> value in the general
          descriptor points to the type-specific descriptor. For keyring
          plugins, this descriptor has the following structure:
        </p><pre class="programlisting">
struct st_mysql_keyring
{
  int interface_version;
  bool (*mysql_key_store)(const char *key_id, const char *key_type,
                          const char* user_id, const void *key, size_t key_len);
  bool (*mysql_key_fetch)(const char *key_id, char **key_type,
                          const char *user_id, void **key, size_t *key_len);
  bool (*mysql_key_remove)(const char *key_id, const char *user_id);
  bool (*mysql_key_generate)(const char *key_id, const char *key_type,
                             const char *user_id, size_t key_len);
};
</pre><p>
          The type-specific descriptor has these members:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              <code class="literal">interface_version</code>: By convention,
              type-specific plugin descriptors begin with the interface
              version for the given plugin type. The server checks
              <code class="literal">interface_version</code> when it loads the
              plugin to see whether the plugin is compatible with it.
              For keyring plugins, the value of the
              <code class="literal">interface_version</code> member is
              <code class="literal">MYSQL_KEYRING_INTERFACE_VERSION</code>
              (defined in <code class="literal">plugin_keyring.h</code>).
            </p></li><li class="listitem"><p>
              <code class="literal">mysql_key_store</code>: A function that
              obfuscates and stores a key in the keyring.
            </p></li><li class="listitem"><p>
              <code class="literal">mysql_key_fetch</code>: A function that
              deobfuscates and retrieves a key from the keyring.
            </p></li><li class="listitem"><p>
              <code class="literal">mysql_key_remove</code>: A function that
              removes a key from the keyring.
            </p></li><li class="listitem"><p>
              <code class="literal">mysql_key_generate</code>: A function that
              generates a new random key and stores it in the keyring.
</p></li></ul>
</div>
<p>
          For the <code class="literal">keyring_file</code> plugin, the
          type-specific descriptor looks like this:
        </p><pre class="programlisting">
static struct st_mysql_keyring keyring_descriptor=
{
  MYSQL_KEYRING_INTERFACE_VERSION,
  mysql_key_store,
  mysql_key_fetch,
  mysql_key_remove,
  mysql_key_generate
};
</pre><p>
          The
          <code class="literal">mysql_key_<em class="replaceable"><code>xxx</code></em></code>
          functions implemented by a keyring plugin are analogous to the
          <code class="literal">my_key_<em class="replaceable"><code>xxx</code></em></code>
          functions exposed by the keyring service API. For example, the
          <code class="literal">mysql_key_store</code> plugin function is
          analogous to the <code class="literal">my_key_store</code> keyring
          service function. For information about the arguments to
          keyring service functions and how they are used, see
          <a class="xref" href="extending-mysql.html#keyring-service" title="28.3.2 The Keyring Service">Section 28.3.2, “The Keyring Service”</a>.
        </p><p>
          To compile and install a plugin library file, use the
          instructions in <a class="xref" href="extending-mysql.html#compiling-plugin-libraries" title="28.2.4.3 Compiling and Installing Plugin Libraries">Section 28.2.4.3, “Compiling and Installing Plugin Libraries”</a>.
          To make the library file available for use, install it in the
          plugin directory (the directory named by the
          <a class="link" href="server-administration.html#sysvar_plugin_dir"><code class="literal">plugin_dir</code></a> system variable).
          For the <code class="literal">keyring_file</code> plugin, it is compiled
          and installed when you build MySQL from source. It is also
          included in binary distributions. The build process produces a
          shared object library with a name of
          <code class="filename">keyring_file.so</code> (the
          <code class="filename">.so</code> suffix might differ depending on your
          platform).
        </p><p>
          Keyring plugins typically are loaded early during the server
          startup process so that they are available to built-in plugins
          and storage engines that might depend on them. For
          <code class="literal">keyring_file</code>, use these lines in the server
          <code class="filename">my.cnf</code> file (adjust the
          <code class="filename">.so</code> suffix for your platform as
          necessary):
        </p><pre class="programlisting">
[mysqld]
early-plugin-load=keyring_file.so
</pre><p>
          For additional information about plugin loading, see
          <a class="xref" href="server-administration.html#server-plugin-loading" title="5.6.1 Installing and Uninstalling Plugins">Section 5.6.1, “Installing and Uninstalling Plugins”</a>.
        </p><p>
          To verify plugin installation, examine the
          <a class="link" href="information-schema.html#plugins-table" title="24.15 The INFORMATION_SCHEMA PLUGINS Table"><code class="literal">INFORMATION_SCHEMA.PLUGINS</code></a> table
          or use the <a class="link" href="sql-syntax.html#show-plugins" title="13.7.6.25 SHOW PLUGINS Syntax"><code class="literal">SHOW PLUGINS</code></a>
          statement (see
          <a class="xref" href="server-administration.html#obtaining-plugin-information" title="5.6.2 Obtaining Server Plugin Information">Section 5.6.2, “Obtaining Server Plugin Information”</a>). For example:
        </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>SELECT PLUGIN_NAME, PLUGIN_STATUS</code></strong>
       <strong class="userinput"><code>FROM INFORMATION_SCHEMA.PLUGINS</code></strong>
       <strong class="userinput"><code>WHERE PLUGIN_NAME LIKE 'keyring%';</code></strong>
+--------------+---------------+
| PLUGIN_NAME  | PLUGIN_STATUS |
+--------------+---------------+
| keyring_file | ACTIVE        |
+--------------+---------------+
</pre><p>
          While the <code class="literal">keyring_file</code> plugin is installed,
          it exposes a system variable that indicates the location of
          the data file it uses for secure information storage:
        </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>SHOW VARIABLES LIKE 'keyring_file%';</code></strong>
+-------------------+----------------------------------+
| Variable_name     | Value                            |
+-------------------+----------------------------------+
| keyring_file_data | /usr/local/mysql/keyring/keyring |
+-------------------+----------------------------------+
</pre><p>
          For a description of the
          <a class="link" href="security.html#sysvar_keyring_file_data"><code class="literal">keyring_file_data</code></a> variable,
          see <a class="xref" href="server-administration.html#server-system-variables" title="5.1.5 Server System Variables">Section 5.1.5, “Server System Variables”</a>.
        </p><p>
          To disable the plugin after testing it, restart the server
          without an <a class="link" href="server-administration.html#option_mysqld_early-plugin-load"><code class="option">--early-plugin-load</code></a>
          option that names the plugin.
</p>
</div>

</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="component-plugin-services"></a>28.3 MySQL Services for Components and Plugins</h2>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="extending-mysql.html#locking-service">28.3.1 The Locking Service</a></span></dt><dt><span class="section"><a href="extending-mysql.html#keyring-service">28.3.2 The Keyring Service</a></span></dt></dl>
</div>
<a class="indexterm" name="idm139899454834960"></a><a class="indexterm" name="idm139899454833888"></a><a class="indexterm" name="idm139899454832400"></a><a class="indexterm" name="idm139899454831328"></a><p>
      MySQL server plugins have access to server <span class="quote">“<span class="quote">plugin
      services.</span>”</span> Similarly, server components have access to
      <span class="quote">“<span class="quote">component services.</span>”</span> The following discussion uses
      the term <span class="quote">“<span class="quote">plugins</span>”</span> but also applies to components.
    </p><p>
      The plugin services interface exposes server functionality that
      plugins can call. It complements the plugin API and has these
      characteristics:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
          Services enable plugins to access code inside the server using
          ordinary function calls. Services are also available to
          user-defined functions (UDFs).
        </p></li><li class="listitem"><p>
          Services are portable and work on multiple platforms.
        </p></li><li class="listitem"><p>
          The interface includes a versioning mechanism so that service
          versions supported by the server can be checked at load time
          against plugin versions. Versioning protects against
          incompatibilities between the version of a service that the
          server provides and the version of the service expected or
          required by a plugin.
        </p></li><li class="listitem"><p>
          For information about plugins for testing plugin services, see
          <a class="ulink" href="http://dev.mysql.com/doc/dev/mysql-server/latest/PAGE_PLUGINS.html" target="_top">Plugins
          for Testing Plugin Services</a>.
</p></li></ul>
</div>
<p>
      The plugin services interface differs from the plugin API as
      follows:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
          The plugin API enables plugins to be used by the server. The
          calling initiative lies with the server to invoke plugins.
          This enables plugins to extend server functionality or
          register to receive notifications about server processing.
        </p></li><li class="listitem"><p>
          The plugin services interface enables plugins to call code
          inside the server. The calling initiative lies with plugins to
          invoke service functions. This enables functionality already
          implemented in the server to be used by many plugins; they
          need not individually implement it themselves.
</p></li></ul>
</div>
<p>
      To determine what component services exist and what functions they
      provide, look in the <code class="filename">include/mysql/components</code>
      directory (and its <code class="filename">services</code> directory) of a
      MySQL source distribution.
    </p><p>
      To determine what plugin services exist and what functions they
      provide, look in the <code class="filename">include/mysql</code> directory
      of a MySQL source distribution. The relevant files are:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
          <code class="filename">plugin.h</code> includes
          <code class="filename">services.h</code>, which is the
          <span class="quote">“<span class="quote">umbrella</span>”</span> header that includes all available
          service-specific header files.
        </p></li><li class="listitem"><p>
          Service-specific headers have names of the form
          <code class="filename">service_<em class="replaceable"><code>xxx</code></em>.h</code>.
</p></li></ul>
</div>
<p>
      The MySQL source code contains internal documentation written
      using Doxygen. This documentation is useful for understanding how
      MySQL works from a developer perspective. The generated Doxygen
      content is available at
      <a class="ulink" href="http://dev.mysql.com/doc/dev/mysql-server/latest/" target="_top">http://dev.mysql.com/doc/dev/mysql-server/latest/</a>; in particular, see
      <a class="ulink" href="http://dev.mysql.com/doc/dev/mysql-server/latest/PAGE_EXTENDING.html" target="_top">http://dev.mysql.com/doc/dev/mysql-server/latest/PAGE_EXTENDING.html</a>.
      It is also possible to generate this content locally from a MySQL
      source distribution using the instructions at
      <a class="xref" href="installing.html#source-installation-doxygen" title="2.9.7 Generating MySQL Doxygen Documentation Content">Section 2.9.7, “Generating MySQL Doxygen Documentation Content”</a>.
    </p><p>
      Available component services include the following:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
          <code class="literal">component_sys_variable_register</code>,
          <code class="literal">component_sys_variable_unregister</code>. Services
          for registering and unregistering system variables.
        </p><a class="indexterm" name="idm139899454805408"></a><a class="indexterm" name="idm139899454803904"></a><a class="indexterm" name="idm139899454802800"></a><a class="indexterm" name="idm139899454801296"></a></li><li class="listitem"><p>
          <code class="literal">log_builtins</code>,
          <code class="literal">log_builtins_string</code>. Services for log
          components. Other
          <code class="literal">log_<em class="replaceable"><code>xxx</code></em></code> services
          may be available, but these are in flux and should not be
          used.
        </p><a class="indexterm" name="idm139899454796880"></a><a class="indexterm" name="idm139899454795392"></a><a class="indexterm" name="idm139899454794304"></a><a class="indexterm" name="idm139899454792816"></a></li><li class="listitem"><p>
          <code class="literal">mysql_service_udf_registration</code>,
          <code class="literal">mysql_service_udf_registration_aggregate</code>:
          Services that enable components and plugins to register and
          unregister scalar and aggregate user-defined-functions (UDFs).
          Using these services, components and plugins can manage UDFs
          for themselves, without the need for
          <a class="link" href="sql-syntax.html#create-function-udf" title="13.7.4.1 CREATE FUNCTION Syntax for User-Defined Functions"><code class="literal">CREATE
          FUNCTION</code></a> and
          <a class="link" href="sql-syntax.html#drop-function-udf" title="13.7.4.2 DROP FUNCTION Syntax"><code class="literal">DROP
          FUNCTION</code></a> statements. UDFs registered using these
          services are listed in the Performance Schema
          <a class="link" href="performance-schema.html#user-defined-functions-table" title="25.11.16.4 The user_defined_functions Table"><code class="literal">user_defined_functions</code></a> table; see
          <a class="xref" href="performance-schema.html#user-defined-functions-table" title="25.11.16.4 The user_defined_functions Table">Section 25.11.16.4, “The user_defined_functions Table”</a>.
        </p><a class="indexterm" name="idm139899454784624"></a><a class="indexterm" name="idm139899454783168"></a><a class="indexterm" name="idm139899454782064"></a><a class="indexterm" name="idm139899454780544"></a></li><li class="listitem"><p>
          <code class="literal">mysql_string</code>: A set of string service APIs.
        </p><a class="indexterm" name="idm139899454777904"></a><a class="indexterm" name="idm139899454776416"></a></li><li class="listitem"><p>
          <code class="literal">pfs_plugin_table</code>: A service for dynamic
          Performance Schema table manipulation.
</p><a class="indexterm" name="idm139899454773776"></a><a class="indexterm" name="idm139899454772288"></a></li></ul>
</div>
<p>
      Available plugin services include the following:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
          <code class="literal">get_sysvar_source</code>: A service that enables
          plugins to retrieve the source of system variable settings.
        </p><a class="indexterm" name="idm139899454768784"></a><a class="indexterm" name="idm139899454767296"></a></li><li class="listitem"><p>
          <code class="literal">locking_service</code>: A service that implements
          locks with three attributes: Lock namespace, lock name, and
          lock mode. This locking interface is available at two levels:
          1) As a C language interface, callable as a plugin service
          from server plugins or user-defined functions; 2) At the SQL
          level, as a set of user-defined functions that map onto calls
          to the service routines. For more information, see
          <a class="xref" href="extending-mysql.html#locking-service" title="28.3.1 The Locking Service">Section 28.3.1, “The Locking Service”</a>.
        </p><a class="indexterm" name="idm139899454763616"></a><a class="indexterm" name="idm139899454762128"></a></li><li class="listitem"><p>
          <code class="literal">my_plugin_log_service</code>: A service that
          enables plugins to report errors and specify error messages.
          The server writes the messages to its error log.
        </p><a class="indexterm" name="idm139899454759408"></a><a class="indexterm" name="idm139899454757920"></a></li><li class="listitem"><p>
          <code class="literal">status_variable_registration</code>. A service for
          registering status variables.
        </p><a class="indexterm" name="idm139899454755280"></a><a class="indexterm" name="idm139899454753776"></a></li><li class="listitem"><p>
          <code class="literal">my_thd_scheduler</code>: A service for plugins to
          select a thread scheduler.
        </p><a class="indexterm" name="idm139899454751120"></a><a class="indexterm" name="idm139899454749632"></a></li><li class="listitem"><p>
          <code class="literal">mysql_keyring</code>: A service for keyring
          storage. For more information, see
          <a class="xref" href="extending-mysql.html#keyring-service" title="28.3.2 The Keyring Service">Section 28.3.2, “The Keyring Service”</a>.
        </p><a class="indexterm" name="idm139899454746320"></a><a class="indexterm" name="idm139899454744832"></a></li><li class="listitem"><p>
          <code class="literal">mysql_password_policy</code>: A service for
          password validation and strength checking.
        </p><a class="indexterm" name="idm139899454742192"></a><a class="indexterm" name="idm139899454740704"></a></li><li class="listitem"><p>
          <code class="literal">plugin_registry_service</code>: MySQL Server
          includes a component-based infrastructure for improving server
          extensibility; see <a class="xref" href="server-administration.html#server-components" title="5.5 MySQL Server Components">Section 5.5, “MySQL Server Components”</a>.
          However, MySQL plugins use an interface that predates the
          component interface. The
          <code class="literal">plugin_registry_service</code> enables plugins to
          access the component registry and its services.
        </p><a class="indexterm" name="idm139899454736480"></a><a class="indexterm" name="idm139899454734992"></a></li><li class="listitem"><p>
          <code class="literal">security_context</code>: A service that enables
          plugins to examine or manipulate thread security contexts.
          This service provides setter and getter routines to access
          attributes of the server <code class="literal">Security_context</code>
          class, which includes attributes such as login user and host,
          authenticated user and host, and client IP address.
        </p><a class="indexterm" name="idm139899454731392"></a><a class="indexterm" name="idm139899454729904"></a></li><li class="listitem"><p>
          <code class="literal">thd_alloc</code>: A memory-allocation service.
        </p><a class="indexterm" name="idm139899454727312"></a><a class="indexterm" name="idm139899454725824"></a></li><li class="listitem"><p>
          <code class="literal">thd_wait</code>: A service for plugins to report
          when they are going to sleep or stall.
</p><a class="indexterm" name="idm139899454723168"></a><a class="indexterm" name="idm139899454721680"></a></li></ul>
</div>
<p>
      The remainder of this section describes how a plugin uses server
      functionality that is available as a service.
    </p><p>
      To use a service or services from within a plugin, the plugin
      source file must include the <code class="filename">plugin.h</code> header
      file to access service-related information:
    </p><pre class="programlisting">
#include &lt;mysql/plugin.h&gt;
</pre><p>
      This does not represent any additional setup cost. A plugin must
      include that file anyway because it contains definitions and
      structures that every plugin needs.
    </p><p>
      To access a service, a plugin calls service functions like any
      other function.
    </p><p>
      To report an error that the server will write to it error log,
      first choose an error level.
      <code class="filename">mysql/service_my_plugin_log.h</code> defines these
      levels:
    </p><pre class="programlisting">
enum plugin_log_level
{
  MY_ERROR_LEVEL,
  MY_WARNING_LEVEL,
  MY_INFORMATION_LEVEL
};
</pre><p>
      Then invoke <code class="literal">my_plugin_log_message()</code>:
    </p><pre class="programlisting">
int my_plugin_log_message(MYSQL_PLUGIN *plugin, enum plugin_log_level level,
                          const char *format, ...);
</pre><p>
      For example:
    </p><pre class="programlisting">
my_plugin_log_message(plugin_ptr, MY_ERROR_LEVEL, "Cannot initialize plugin");
</pre><p>
      Some services <span class="emphasis"><em>for</em></span> plugins may be provided
      <span class="emphasis"><em>by</em></span> plugins and thus are available only if the
      service-providing plugin is loaded. Any MySQL component that uses
      such a service should check whether the service is available.
    </p><p>
      When you build your plugin, use the
      <code class="literal">-lmysqlservices</code> flag at link time to link in
      the <code class="literal">libmysqlservices</code> library. For example, for
      <span class="command"><strong>CMake</strong></span>, put this in the top-level
      <code class="filename">CMakeLists.txt</code> file:
    </p><pre class="programlisting">
FIND_LIBRARY(MYSQLSERVICES_LIB mysqlservices
 PATHS "${MYSQL_SRCDIR}/libservices" NO_DEFAULT_PATH)
</pre><p>
      Put this in the <code class="filename">CMakeLists.txt</code> file in the
      directory containing the plugin source:
    </p><pre class="programlisting">
# the plugin needs the mysql services library for error logging
TARGET_LINK_LIBRARIES (<em class="replaceable"><code>your_plugin_library_name</code></em> ${MYSQLSERVICES_LIB})
</pre>
<div class="section">

<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="locking-service"></a>28.3.1 The Locking Service</h3>

</div>

</div>

</div>

<div class="toc">
<dl class="toc"><dt><span class="section"><a href="extending-mysql.html#locking-service-c-interface">28.3.1.1 The Locking Service C Interface</a></span></dt><dt><span class="section"><a href="extending-mysql.html#locking-service-udf-interface">28.3.1.2 The Locking Service UDF Interface</a></span></dt></dl>
</div>
<a class="indexterm" name="idm139899454702400"></a><a class="indexterm" name="idm139899454700912"></a><p>
        Distributions provide a locking interface that is available at
        two levels:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            As a C language interface, callable as a plugin service from
            server plugins or user-defined functions
          </p></li><li class="listitem"><p>
            At the SQL level, as a set of user-defined functions that
            map onto calls to the service routines
</p></li></ul>
</div>
<p>
        For general information about plugin services, see
        <a class="xref" href="extending-mysql.html#component-plugin-services" title="28.3 MySQL Services for Components and Plugins">Section 28.3, “MySQL Services for Components and Plugins”</a>. For general
        information about user-defined functions, see
        <a class="xref" href="extending-mysql.html#adding-udf" title="28.4.2 Adding a New User-Defined Function">Section 28.4.2, “Adding a New User-Defined Function”</a>.
      </p><p>
        The locking interface has these characteristics:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            Locks have three attributes: Lock namespace, lock name, and
            lock mode:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                Locks are identified by the combination of namespace and
                lock name. The namespace enables different applications
                to use the same lock names without colliding by creating
                locks in separate namespaces. For example, if
                applications A and B use namespaces of
                <code class="literal">ns1</code> and <code class="literal">ns2</code>,
                respectively, each application can use lock names
                <code class="literal">lock1</code> and <code class="literal">lock2</code>
                without interfering with the other application.
              </p></li><li class="listitem"><p>
                A lock mode is either read or write. Read locks are
                shared: If a session has a read lock on a given lock
                identifier, other sessions can acquire a read lock on
                the same identifier. Write locks are exclusive: If a
                session has a write lock on a given lock identifier,
                other sessions cannot acquire a read or write lock on
                the same identifier.
</p></li></ul>
</div>
</li><li class="listitem"><p>
            Namespace and lock names must be
            non-<code class="literal">NULL</code>, nonempty, and have a maximum
            length of 64 characters. A namespace or lock name specified
            as <code class="literal">NULL</code>, the empty string, or a string
            longer than 64 characters results in an
            <a class="link" href="error-handling.html#error_er_locking_service_wrong_name"><code class="literal">ER_LOCKING_SERVICE_WRONG_NAME</code></a>
            error.
          </p></li><li class="listitem"><p>
            The locking interface treats namespace and lock names as
            binary strings, so comparisons are case-sensitive.
          </p></li><li class="listitem"><p>
            The locking interface provides functions to acquire locks
            and release locks. No special privilege is required to call
            these functions. Privilege checking is the responsibility of
            the calling application.
          </p></li><li class="listitem"><p>
            Locks can be waited for if not immediately available. Lock
            acquisition calls take an integer timeout value that
            indicates how many seconds to wait to acquire locks before
            giving up. If the timeout is reached without successful lock
            acquisition, an
            <a class="link" href="error-handling.html#error_er_locking_service_timeout"><code class="literal">ER_LOCKING_SERVICE_TIMEOUT</code></a>
            error occurs. If the timeout is 0, there is no waiting and
            the call produces an error if locks cannot be acquired
            immediately.
          </p></li><li class="listitem"><p>
            The locking interface detects deadlock between
            lock-acquisition calls in different sessions. In this case,
            the locking service chooses a caller and terminates its
            lock-acquisition request with an
            <a class="link" href="error-handling.html#error_er_locking_service_deadlock"><code class="literal">ER_LOCKING_SERVICE_DEADLOCK</code></a>
            error. This error does not cause transactions to roll back.
            To choose a session in case of deadlock, the locking service
            prefers sessions that hold read locks over sessions that
            hold write locks.
          </p></li><li class="listitem"><p>
            A session can acquire multiple locks with a single
            lock-acquisition call. For a given call, lock acquisition is
            atomic: The call succeeeds if all locks are acquired. If
            acquisition of any lock fails, the call acquires no locks
            and fails, typically with an
            <a class="link" href="error-handling.html#error_er_locking_service_timeout"><code class="literal">ER_LOCKING_SERVICE_TIMEOUT</code></a>
            or
            <a class="link" href="error-handling.html#error_er_locking_service_deadlock"><code class="literal">ER_LOCKING_SERVICE_DEADLOCK</code></a>
            error.
          </p></li><li class="listitem"><p>
            A session can acquire multiple locks for the same lock
            identifier (namespace and lock name combination). These lock
            instances can be read locks, write locks, or a mix of both.
          </p></li><li class="listitem"><p>
            Locks acquired within a session are released explicitly by
            calling a release-locks function, or implicitly when the
            session terminates (either normally or abnormally). Locks
            are not released when transactions commit or roll back.
          </p></li><li class="listitem"><p>
            Within a session, all locks for a given namespace when
            released are released together.
</p></li></ul>
</div>
<p>
        The interface provided by the locking service is distinct from
        that provided by <a class="link" href="functions.html#function_get-lock"><code class="literal">GET_LOCK()</code></a> and
        related SQL functions (see
        <a class="xref" href="functions.html#miscellaneous-functions" title="12.22 Miscellaneous Functions">Section 12.22, “Miscellaneous Functions”</a>). For example,
        <a class="link" href="functions.html#function_get-lock"><code class="literal">GET_LOCK()</code></a> does not implement
        namespaces and provides only exclusive locks, not distinct read
        and write locks.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="locking-service-c-interface"></a>28.3.1.1 The Locking Service C Interface</h4>
</div>
</div>
</div>
<p>
          This section describes how to use the locking service C
          language interface. To use the UDF interface instead, see
          <a class="xref" href="extending-mysql.html#locking-service-udf-interface" title="28.3.1.2 The Locking Service UDF Interface">Section 28.3.1.2, “The Locking Service UDF Interface”</a> For general
          characteristics of the locking service interface, see
          <a class="xref" href="extending-mysql.html#locking-service" title="28.3.1 The Locking Service">Section 28.3.1, “The Locking Service”</a>. For general information
          about plugin services, see
          <a class="xref" href="extending-mysql.html#component-plugin-services" title="28.3 MySQL Services for Components and Plugins">Section 28.3, “MySQL Services for Components and Plugins”</a>.
        </p><p>
          Source files that use the locking service should include this
          header file:
        </p><pre class="programlisting">
#include &lt;mysql/service_locking.h&gt;
</pre><p>
          To acquire one or more locks, call this function:
        </p><a class="indexterm" name="idm139899454659536"></a><a class="indexterm" name="idm139899454658016"></a><pre class="programlisting">
int mysql_acquire_locking_service_locks(MYSQL_THD opaque_thd,
                                        const char* lock_namespace,
                                        const char**lock_names,
                                        size_t lock_num,
                                        enum enum_locking_service_lock_type lock_type,
                                        unsigned long lock_timeout);
</pre><p>
          The arguments have these meanings:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              <code class="literal">opaque_thd</code>: A thread handle. If
              specified as <code class="literal">NULL</code>, the handle for the
              current thread is used.
            </p></li><li class="listitem"><p>
              <code class="literal">lock_namespace</code>: A null-terminated
              string that indicates the lock namespace.
            </p></li><li class="listitem"><p>
              <code class="literal">lock_names</code>: An array of null-terminated
              strings that provides the names of the locks to acquire.
            </p></li><li class="listitem"><p>
              <code class="literal">lock_num</code>: The number of names in the
              <code class="literal">lock_names</code> array.
            </p></li><li class="listitem"><p>
              <code class="literal">lock_type</code>: The lock mode, either
              <code class="literal">LOCKING_SERVICE_READ</code> or
              <code class="literal">LOCKING_SERVICE_WRITE</code> to acquire read
              locks or write locks, respectively.
            </p></li><li class="listitem"><p>
              <code class="literal">lock_timeout</code>: An integer number of
              seconds to wait to acquire the locks before giving up.
</p></li></ul>
</div>
<p>
          To release locks acquired for a given namespace, call this
          function:
        </p><a class="indexterm" name="idm139899454641856"></a><a class="indexterm" name="idm139899454640336"></a><pre class="programlisting">
int mysql_release_locking_service_locks(MYSQL_THD opaque_thd,
                                        const char* lock_namespace);
</pre><p>
          The arguments have these meanings:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              <code class="literal">opaque_thd</code>: A thread handle. If
              specified as <code class="literal">NULL</code>, the handle for the
              current thread is used.
            </p></li><li class="listitem"><p>
              <code class="literal">lock_namespace</code>: A null-terminated
              string that indicates the lock namespace.
</p></li></ul>
</div>
<p>
          Locks acquired or waited for by the locking service can be
          monitored at the SQL level using the Performance Schema. For
          details, see <a class="xref" href="extending-mysql.html#locking-service-monitoring" title="28.3.1.2.3 Locking Service Monitoring">Section 28.3.1.2.3, “Locking Service Monitoring”</a>.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="locking-service-udf-interface"></a>28.3.1.2 The Locking Service UDF Interface</h4>

</div>

</div>

</div>
<p>
          This section describes how to use the locking service
          user-defined function (UDF) interface. To use the C language
          interface instead, see
          <a class="xref" href="extending-mysql.html#locking-service-c-interface" title="28.3.1.1 The Locking Service C Interface">Section 28.3.1.1, “The Locking Service C Interface”</a> For general
          characteristics of the locking service interface, see
          <a class="xref" href="extending-mysql.html#locking-service" title="28.3.1 The Locking Service">Section 28.3.1, “The Locking Service”</a>. For general information
          about user-defined functions, see
          <a class="xref" href="extending-mysql.html#adding-udf" title="28.4.2 Adding a New User-Defined Function">Section 28.4.2, “Adding a New User-Defined Function”</a>.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="locking-service-udf-installation"></a>28.3.1.2.1 Installing or Uninstalling the UDF Locking Interface</h5>
</div>
</div>
</div>
<a class="indexterm" name="idm139899454626704"></a><a class="indexterm" name="idm139899454625216"></a><p>
            The locking service routines described in
            <a class="xref" href="extending-mysql.html#locking-service-c-interface" title="28.3.1.1 The Locking Service C Interface">Section 28.3.1.1, “The Locking Service C Interface”</a> need not be
            installed because they are built into the server. The same
            is not true of the user-defined functions (UDFs) that map
            onto calls to the service routines: The UDFs must be
            installed before use. This section describes how to do that.
            For general information about UDF installation, see
            <a class="xref" href="extending-mysql.html#udf-compiling" title="28.4.2.5 UDF Compiling and Installing">Section 28.4.2.5, “UDF Compiling and Installing”</a>.
          </p><p>
            The locking service UDFs are implemented in a plugin library
            file located in the directory named by the
            <a class="link" href="server-administration.html#sysvar_plugin_dir"><code class="literal">plugin_dir</code></a> system variable.
            The file base name is <code class="literal">locking_service</code>.
            The file name suffix differs per platform (for example,
            <code class="filename">.so</code> for Unix and Unix-like systems,
            <code class="filename">.dll</code> for Windows).
          </p><p>
            To install the locking service UDFs, use the
            <a class="link" href="sql-syntax.html#create-function" title="13.1.13 CREATE FUNCTION Syntax"><code class="literal">CREATE FUNCTION</code></a> statement
            (adjust the <code class="filename">.so</code> suffix for your
            platform as necessary):
          </p><pre class="programlisting">
CREATE FUNCTION service_get_read_locks RETURNS INT SONAME 'locking_service.so';
CREATE FUNCTION service_get_write_locks RETURNS INT SONAME 'locking_service.so';
CREATE FUNCTION service_release_locks RETURNS INT SONAME 'locking_service.so';
</pre><p>
            If the UDFs are used on a master replication server, install
            them on all slave servers as well to avoid replication
            problems.
          </p><p>
            Once installed, the UDFs remain installed until uninstalled.
            To remove them, use the <a class="link" href="sql-syntax.html#drop-function" title="13.1.24 DROP FUNCTION Syntax"><code class="literal">DROP
            FUNCTION</code></a> statement:
          </p><pre class="programlisting">
DROP FUNCTION service_get_read_locks;
DROP FUNCTION service_get_write_locks;
DROP FUNCTION service_release_locks;
</pre>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="locking-service-udf-usage"></a>28.3.1.2.2 Using the UDF Locking Interface</h5>

</div>

</div>

</div>
<p>
            Before using the locking service UDFs, install them
            according to the instructions provided at
            <a class="xref" href="extending-mysql.html#locking-service-udf-installation" title="28.3.1.2.1 Installing or Uninstalling the UDF Locking Interface">Section 28.3.1.2.1, “Installing or Uninstalling the UDF Locking Interface”</a>.
          </p><p>
            To acquire one or more read locks, call this function:
          </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>SELECT service_get_read_locks('mynamespace', 'rlock1', 'rlock2', 10);</code></strong>
+---------------------------------------------------------------+
| service_get_read_locks('mynamespace', 'rlock1', 'rlock2', 10) |
+---------------------------------------------------------------+
|                                                             1 |
+---------------------------------------------------------------+
</pre><p>
            The first argument is the lock namespace. The final argument
            is an integer timeout indicating how many seconds to wait to
            acquire the locks before giving up. The arguments in between
            are the lock names.
          </p><p>
            For the example just shown, the function acquires locks with
            lock identifiers <code class="literal">(mynamespace, rlock1)</code>
            and <code class="literal">(mynamespace, rlock2)</code>.
          </p><p>
            To acquire write locks rather than read locks, call this
            function:
          </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>SELECT service_get_write_locks('mynamespace', 'wlock1', 'wlock2', 10);</code></strong>
+----------------------------------------------------------------+
| service_get_write_locks('mynamespace', 'wlock1', 'wlock2', 10) |
+----------------------------------------------------------------+
|                                                              1 |
+----------------------------------------------------------------+
</pre><p>
            In this case, the lock identifiers are
            <code class="literal">(mynamespace, wlock1)</code> and
            <code class="literal">(mynamespace, wlock2)</code>.
          </p><p>
            To release all locks for a namespace, use this function:
          </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>SELECT service_release_locks('mynamespace');</code></strong>
+--------------------------------------+
| service_release_locks('mynamespace') |
+--------------------------------------+
|                                    1 |
+--------------------------------------+
</pre><p>
            Each locking function returns nonzero for success. If the
            function fails, an error occurs. For example, the following
            error occurs because lock names cannot be empty:
          </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>SELECT service_get_read_locks('mynamespace', '', 10);</code></strong>
ERROR 3131 (42000): Incorrect locking service lock name ''.
</pre><p>
            A session can acquire multiple locks for the same lock
            identifier. As long as a different session does not have a
            write lock for an identifier, the session can acquire any
            number of read or write locks. Each lock request for the
            identifier acquires a new lock. The following statements
            acquire three write locks with the same identifier, then
            three read locks for the same identifier:
          </p><pre class="programlisting">
SELECT service_get_write_locks('ns', 'lock1', 'lock1', 'lock1', 0);
SELECT service_get_read_locks('ns', 'lock1', 'lock1', 'lock1', 0);
</pre><p>
            If you examine the Performance Schema
            <code class="literal">metadata_locks</code> table at this point, you
            will find that the session holds six distinct locks with the
            same <code class="literal">(ns, lock1)</code> identifier. (For
            details, see <a class="xref" href="extending-mysql.html#locking-service-monitoring" title="28.3.1.2.3 Locking Service Monitoring">Section 28.3.1.2.3, “Locking Service Monitoring”</a>.)
          </p><p>
            Because the session holds at least one write lock on
            <code class="literal">(ns, lock1)</code>, no other session can acquire
            a lock for it, either read or write. If the session held
            only read locks for the identifier, other sessions could
            acquire read locks for it, but not write locks.
          </p><p>
            Locks for a single lock-acquisition call are acquired
            atomically, but atomicity does not hold across calls. Thus,
            for a statement such as the following, where
            <code class="literal">service_get_write_locks()</code> is called once
            per row of the result set, atomicity holds for each
            individual call, but not for the statement as a whole:
          </p><pre class="programlisting">
SELECT service_get_write_locks('ns', 'lock1', 'lock2', 0) FROM t1 WHERE ... ;
</pre>
<div class="caution" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Caution
</div>
<p>
              Because the locking service returns a separate lock for
              each successful request for a given lock identifier, it is
              possible for a single statement to acquire a large number
              of locks. For example:
            </p><pre class="programlisting">
INSERT INTO ... SELECT service_get_write_locks('ns', t1.col_name, 0) FROM t1;
</pre><p>
              These types of statements may have certain adverse
              effects. For example, if the statement fails part way
              through and rolls back, locks acquired up to the point of
              failure will still exist. If the intent is for there to be
              a correspondence between rows inserted and locks acquired,
              that intent will not be satisfied. Also, if it is
              important that locks are granted in a certain order, be
              aware that result set order may differ depending on which
              execution plan the optimizer chooses. For these reasons,
              it may be best to limit applications to a single
              lock-acquisition call per statement.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="locking-service-monitoring"></a>28.3.1.2.3 Locking Service Monitoring</h5>

</div>

</div>

</div>
<p>
            The locking service is implemented using the MySQL Server
            metadata locks framework, so you monitor locking service
            locks acquired or waited for by examining the Performance
            Schema <code class="literal">metadata_locks</code> table.
          </p><p>
            First, enable the metadata lock instrument:
          </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>UPDATE performance_schema.setup_instruments SET ENABLED = 'YES'</code></strong>
    -&gt; <strong class="userinput"><code>WHERE NAME = 'wait/lock/metadata/sql/mdl';</code></strong>
</pre><p>
            Then acquire some locks and check the contents of the
            <code class="literal">metadata_locks</code> table:
          </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>SELECT service_get_write_locks('mynamespace', 'lock1', 0);</code></strong>
+----------------------------------------------------+
| service_get_write_locks('mynamespace', 'lock1', 0) |
+----------------------------------------------------+
|                                                  1 |
+----------------------------------------------------+
mysql&gt; <strong class="userinput"><code>SELECT service_get_read_locks('mynamespace', 'lock2', 0);</code></strong>
+---------------------------------------------------+
| service_get_read_locks('mynamespace', 'lock2', 0) |
+---------------------------------------------------+
|                                                 1 |
+---------------------------------------------------+
mysql&gt; <strong class="userinput"><code>SELECT OBJECT_TYPE, OBJECT_SCHEMA, OBJECT_NAME, LOCK_TYPE, LOCK_STATUS</code></strong>
    -&gt; <strong class="userinput"><code>FROM performance_schema.metadata_locks</code></strong>
    -&gt; <strong class="userinput"><code>WHERE OBJECT_TYPE = 'LOCKING SERVICE'\G</code></strong>
*************************** 1. row ***************************
  OBJECT_TYPE: LOCKING SERVICE
OBJECT_SCHEMA: mynamespace
  OBJECT_NAME: lock1
    LOCK_TYPE: EXCLUSIVE
  LOCK_STATUS: GRANTED
*************************** 2. row ***************************
  OBJECT_TYPE: LOCKING SERVICE
OBJECT_SCHEMA: mynamespace
  OBJECT_NAME: lock2
    LOCK_TYPE: SHARED
  LOCK_STATUS: GRANTED
</pre><p>
            Locking service locks have an <code class="literal">OBJECT_TYPE</code>
            value of <code class="literal">LOCKING SERVICE</code>. This is
            distinct from, for example, locks acquired with the
            <a class="link" href="functions.html#function_get-lock"><code class="literal">GET_LOCK()</code></a> function, which
            have an <code class="literal">OBJECT_TYPE</code> of <code class="literal">USER
            LEVEL LOCK</code>.
          </p><p>
            The lock namespace, name, and mode appear in the
            <code class="literal">OBJECT_SCHEMA</code>,
            <code class="literal">OBJECT_NAME</code>, and
            <code class="literal">LOCK_TYPE</code> columns. Read and write locks
            have <code class="literal">LOCK_TYPE</code> values of
            <code class="literal">SHARED</code> and <code class="literal">EXCLUSIVE</code>,
            respectively.
          </p><p>
            The <code class="literal">LOCK_STATUS</code> value is
            <code class="literal">GRANTED</code> for an acquired lock,
            <code class="literal">PENDING</code> for a lock that is being waited
            for. You will see <code class="literal">PENDING</code> if one session
            holds a write lock and another session is attempting to
            acquire a lock having the same identifier.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="locking-service-udf-reference"></a>28.3.1.2.4 Locking Service UDF Interface Reference</h5>

</div>

</div>

</div>
<p>
            The SQL interface to the locking service implements the
            user-defined functions described in this section. For usage
            examples, see <a class="xref" href="extending-mysql.html#locking-service-udf-usage" title="28.3.1.2.2 Using the UDF Locking Interface">Section 28.3.1.2.2, “Using the UDF Locking Interface”</a>.
          </p><p>
            The functions share these characteristics:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                The return value is nonzero for success. Otherwise, an
                error occurs.
              </p></li><li class="listitem"><p>
                Namespace and lock names must be
                non-<code class="literal">NULL</code>, nonempty, and have a
                maximum length of 64 characters.
              </p></li><li class="listitem"><p>
                Timeout values must be integers indicating how many
                seconds to wait to acquire locks before giving up with
                an error. If the timeout is 0, there is no waiting and
                the function produces an error if locks cannot be
                acquired immediately.
</p></li></ul>
</div>
<p>
            These locking service UDFs are available:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                <code class="literal">service_get_read_locks(<em class="replaceable"><code>namespace</code></em>,
                <em class="replaceable"><code>lock_name</code></em>[,
                <em class="replaceable"><code>lock_name</code></em>] ...,
                <em class="replaceable"><code>timeout</code></em>)</code>
              </p><a class="indexterm" name="idm139899454546368"></a><a class="indexterm" name="idm139899454544912"></a><p>
                Acquires one or more read (shared) locks in the given
                namespace using the given lock names, timing out with an
                error if the locks are not acquired within the given
                timeout value.
              </p></li><li class="listitem"><p>
                <code class="literal">service_get_write_locks(<em class="replaceable"><code>namespace</code></em>,
                <em class="replaceable"><code>lock_name</code></em>[,
                <em class="replaceable"><code>lock_name</code></em>] ...,
                <em class="replaceable"><code>timeout</code></em>)</code>
              </p><a class="indexterm" name="idm139899454539520"></a><a class="indexterm" name="idm139899454538016"></a><p>
                Acquires one or more write (exclusive) locks in the
                given namespace using the given lock names, timing out
                with an error if the locks are not acquired within the
                given timeout value.
              </p></li><li class="listitem"><p>
                <code class="literal">service_release_locks(<em class="replaceable"><code>namespace</code></em>)</code>
              </p><a class="indexterm" name="idm139899454533984"></a><a class="indexterm" name="idm139899454532480"></a><p>
                For the given namespace, releases all locks that were
                acquired within the current session using
                <code class="literal">service_get_read_locks()</code> and
                <code class="literal">service_get_write_locks()</code>.
              </p><p>
                It is not an error for there to be no locks in the
                namespace.
</p></li></ul>
</div>

</div>

</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="keyring-service"></a>28.3.2 The Keyring Service</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm139899454526704"></a><a class="indexterm" name="idm139899454525216"></a><p>
        MySQL Server supports a keyring service that enables internal
        server components and plugins to securely store sensitive
        information for later retrieval. This section describes how to
        use the keyring service functions to store, retrieve, and remove
        keys in the MySQL keyring keystore. An SQL interface to the
        keyring service functions is also available as a set of
        user-defined functions (UDFs); see
        <a class="xref" href="security.html#keyring-udfs-general-purpose" title="6.5.4.8 General-Purpose Keyring Key-Management Functions">Section 6.5.4.8, “General-Purpose Keyring Key-Management Functions”</a>. For general
        keyring information, see <a class="xref" href="security.html#keyring" title="6.5.4 The MySQL Keyring">Section 6.5.4, “The MySQL Keyring”</a>.
      </p><p>
        The keyring service uses whatever underlying keyring plugin is
        enabled, if any. If no keyring plugin is enabled, keyring
        service calls fail.
      </p><p>
        A <span class="quote">“<span class="quote">record</span>”</span> in the keystore consists of data (the
        key itself) and a unique identifier through which the key is
        accessed. The identifier has two parts:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">key_id</code>: The key ID or name.
            <code class="literal">key_id</code> values that begin with
            <code class="literal">mysql_</code> are reserved by MySQL Server.
          </p></li><li class="listitem"><p>
            <code class="literal">user_id</code>: The session effective user ID.
            If there is no user context, this value can be
            <code class="literal">NULL</code>. The value need not actually be a
            <span class="quote">“<span class="quote">user</span>”</span>; the meaning depends on the application.
          </p><p>
            Functions that implement the keyring UDF interface pass the
            value of <a class="link" href="functions.html#function_current-user"><code class="literal">CURRENT_USER()</code></a> as
            the <code class="literal">user_id</code> value to keyring service
            functions.
</p></li></ul>
</div>
<p>
        The keyring service functions have these characteristics in
        common:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            Each function returns 0 for success, 1 for failure.
          </p></li><li class="listitem"><p>
            The <code class="literal">key_id</code> and <code class="literal">user_id</code>
            arguments form a unique combination indicating which key in
            the keyring to use.
          </p></li><li class="listitem"><p>
            The <code class="literal">key_type</code> argument provides additional
            information about the key, such as its encryption method or
            intended use.
          </p></li><li class="listitem"><p>
            Keyring service functions treat key IDs, user names, types,
            and values as binary strings, so comparisons are case
            sensitive. For example, IDs of <code class="literal">MyKey</code> and
            <code class="literal">mykey</code> refer to different keys.
</p></li></ul>
</div>
<p>
        These keyring service functions are available:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">my_key_fetch()</code>
          </p><a class="indexterm" name="idm139899454501408"></a><a class="indexterm" name="idm139899454500320"></a><p>
            Deobfuscates and retrieves a key from the keyring, along
            with its type. The function allocates the memory for the
            buffers used to store the returned key and key type. The
            caller should zero or obfuscate the memory when it is no
            longer needed, then free it.
          </p><p>
            Syntax:
          </p><pre class="programlisting">
bool my_key_fetch(const char *key_id, const char **key_type,
                  const char* user_id, void **key, size_t *key_len)
</pre><p>
            Arguments:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                <code class="literal">key_id</code>, <code class="literal">user_id</code>:
                Null-terminated strings that as a pair form a unique
                identifier indicating which key to fetch.
              </p></li><li class="listitem"><p>
                <code class="literal">key_type</code>: The address of a buffer
                pointer. The function stores into it a pointer to a
                null-terminated string that provides additional
                information about the key (stored when the key was
                added).
              </p></li><li class="listitem"><p>
                <code class="literal">key</code>: The address of a buffer pointer.
                The function stores into it a pointer to the buffer
                containing the fetched key data.
              </p></li><li class="listitem"><p>
                <code class="literal">key_len</code>: The address of a variable
                into which the function stores the size in bytes of the
                <code class="literal">*key</code> buffer.
</p></li></ul>
</div>
<p>
            Return values:
          </p><p>
            Returns 0 for success, 1 for failure.
          </p></li><li class="listitem"><p>
            <code class="literal">my_key_generate()</code>
          </p><a class="indexterm" name="idm139899454485744"></a><a class="indexterm" name="idm139899454484640"></a><p>
            Generates a new random key of a given type and length and
            stores it in the keyring. The key has a length of
            <code class="literal">key_len</code> and is associated with the
            identifier formed from <code class="literal">key_id</code> and
            <code class="literal">user_id</code>. The type and length values must
            be consistent with the values supported by the underlying
            keyring plugin. See <a class="xref" href="security.html#keyring-key-types" title="6.5.4.7 Supported Keyring Key Types">Section 6.5.4.7, “Supported Keyring Key Types”</a>.
          </p><p>
            Syntax:
          </p><pre class="programlisting">
bool my_key_generate(const char *key_id, const char *key_type,
                     const char *user_id, size_t key_len)
</pre><p>
            Arguments:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                <code class="literal">key_id</code>, <code class="literal">user_id</code>:
                Null-terminated strings that as a pair form a unique
                identifier for the key to be generated.
              </p></li><li class="listitem"><p>
                <code class="literal">key_type</code>: A null-terminated string
                that provides additional information about the key.
              </p></li><li class="listitem"><p>
                <code class="literal">key_len</code>: The size in bytes of the key
                to be generated.
</p></li></ul>
</div>
<p>
            Return values:
          </p><p>
            Returns 0 for success, 1 for failure.
          </p></li><li class="listitem"><p>
            <code class="literal">my_key_remove()</code>
          </p><a class="indexterm" name="idm139899454469744"></a><a class="indexterm" name="idm139899454468640"></a><p>
            Removes a key from the keyring.
          </p><p>
            Syntax:
          </p><pre class="programlisting">
bool my_key_remove(const char *key_id, const char* user_id)
</pre><p>
            Arguments:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                <code class="literal">key_id</code>, <code class="literal">user_id</code>:
                Null-terminated strings that as a pair form a unique
                identifier for the key to be removed.
</p></li></ul>
</div>
<p>
            Return values:
          </p><p>
            Returns 0 for success, 1 for failure.
          </p></li><li class="listitem"><p>
            <code class="literal">my_key_store()</code>
          </p><a class="indexterm" name="idm139899454460048"></a><a class="indexterm" name="idm139899454458960"></a><p>
            Obfuscates and stores a key in the keyring.
          </p><p>
            Syntax:
          </p><pre class="programlisting">
bool my_key_store(const char *key_id, const char *key_type,
                  const char* user_id, void *key, size_t key_len)
</pre><p>
            Arguments:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                <code class="literal">key_id</code>, <code class="literal">user_id</code>:
                Null-terminated strings that as a pair form a unique
                identifier for the key to be stored.
              </p></li><li class="listitem"><p>
                <code class="literal">key_type</code>: A null-terminated string
                that provides additional information about the key.
              </p></li><li class="listitem"><p>
                <code class="literal">key</code>: The buffer containing the key
                data to be stored.
              </p></li><li class="listitem"><p>
                <code class="literal">key_len</code>: The size in bytes of the
                <code class="literal">key</code> buffer.
</p></li></ul>
</div>
<p>
            Return values:
          </p><p>
            Returns 0 for success, 1 for failure.
</p></li></ul>
</div>

</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="adding-functions"></a>28.4 Adding New Functions to MySQL</h2>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="extending-mysql.html#udf-features">28.4.1 Features of the User-Defined Function Interface</a></span></dt><dt><span class="section"><a href="extending-mysql.html#adding-udf">28.4.2 Adding a New User-Defined Function</a></span></dt><dt><span class="section"><a href="extending-mysql.html#adding-native-function">28.4.3 Adding a New Native Function</a></span></dt></dl>
</div>
<a class="indexterm" name="idm139899454444832"></a><a class="indexterm" name="idm139899454443408"></a><a class="indexterm" name="idm139899454441920"></a><a class="indexterm" name="idm139899454440432"></a><a class="indexterm" name="idm139899454438944"></a><p>
      There are three ways to add new functions to MySQL:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
          You can add functions through the user-defined function (UDF)
          interface. User-defined functions are compiled as library
          files and then added to and removed from the server
          dynamically using the <a class="link" href="sql-syntax.html#create-function" title="13.1.13 CREATE FUNCTION Syntax"><code class="literal">CREATE
          FUNCTION</code></a> and <a class="link" href="sql-syntax.html#drop-function" title="13.1.24 DROP FUNCTION Syntax"><code class="literal">DROP
          FUNCTION</code></a> statements. See
          <a class="xref" href="sql-syntax.html#create-function-udf" title="13.7.4.1 CREATE FUNCTION Syntax for User-Defined Functions">Section 13.7.4.1, “CREATE FUNCTION Syntax for User-Defined Functions”</a>.
        </p></li><li class="listitem"><p>
          You can add functions as native (built-in) MySQL functions.
          Native functions are compiled into the
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> server and become available on a
          permanent basis.
        </p></li><li class="listitem"><p>
          Another way to add functions is by creating stored functions.
          These are written using SQL statements rather than by
          compiling object code. The syntax for writing stored functions
          is not covered here. See <a class="xref" href="stored-programs-views.html#stored-routines" title="23.2 Using Stored Routines (Procedures and Functions)">Section 23.2, “Using Stored Routines (Procedures and Functions)”</a>.
</p></li></ul>
</div>
<p>
      Each method of creating compiled functions has advantages and
      disadvantages:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
          If you write user-defined functions, you must install object
          files in addition to the server itself. If you compile your
          function into the server, you need not do that.
        </p></li><li class="listitem"><p>
          Native functions require you to modify a source distribution.
          UDFs do not. You can add UDFs to a binary MySQL distribution.
          No access to MySQL source is necessary.
        </p></li><li class="listitem"><p>
          If you upgrade your MySQL distribution, you can continue to
          use your previously installed UDFs, unless you upgrade to a
          newer version for which the UDF interface changes. For native
          functions, you must repeat your modifications each time you
          upgrade.
</p></li></ul>
</div>
<p>
      Whichever method you use to add new functions, they can be invoked
      in SQL statements just like native functions such as
      <a class="link" href="functions.html#function_abs"><code class="literal">ABS()</code></a> or
      <a class="link" href="functions.html#function_soundex"><code class="literal">SOUNDEX()</code></a>.
    </p><p>
      See <a class="xref" href="language-structure.html#function-resolution" title="9.2.4 Function Name Parsing and Resolution">Section 9.2.4, “Function Name Parsing and Resolution”</a>, for the rules
      describing how the server interprets references to different kinds
      of functions.
    </p><p>
      The following sections describe features of the UDF interface,
      provide instructions for writing UDFs, discuss security
      precautions that MySQL takes to prevent UDF misuse, and describe
      how to add native MySQL functions.
    </p><p>
      For example source code that illustrates how to write UDFs, take a
      look at the <code class="filename">sql/udf_example.cc</code> file that is
      provided in MySQL source distributions.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
        The MySQL source code contains internal documentation written
        using Doxygen. This documentation is useful for understanding
        how MySQL works from a developer perspective. The generated
        Doxygen content is available at
        <a class="ulink" href="http://dev.mysql.com/doc/dev/mysql-server/latest/" target="_top">http://dev.mysql.com/doc/dev/mysql-server/latest/</a>. It is also
        possible to generate this content locally from a MySQL source
        distribution using the instructions at
        <a class="xref" href="installing.html#source-installation-doxygen" title="2.9.7 Generating MySQL Doxygen Documentation Content">Section 2.9.7, “Generating MySQL Doxygen Documentation Content”</a>.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="udf-features"></a>28.4.1 Features of the User-Defined Function Interface</h3>

</div>

</div>

</div>
<p>
        The MySQL interface for user-defined functions provides the
        following features and capabilities:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            Functions can return string, integer, or real values and can
            accept arguments of those same types.
          </p></li><li class="listitem"><p>
            You can define simple functions that operate on a single row
            at a time, or aggregate functions that operate on groups of
            rows.
          </p></li><li class="listitem"><p>
            Information is provided to functions that enables them to
            check the number, types, and names of the arguments passed
            to them.
          </p></li><li class="listitem"><p>
            You can tell MySQL to coerce arguments to a given type
            before passing them to a function.
          </p></li><li class="listitem"><p>
            You can indicate that a function returns
            <code class="literal">NULL</code> or that an error occurred.
</p></li></ul>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="adding-udf"></a>28.4.2 Adding a New User-Defined Function</h3>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="extending-mysql.html#udf-calling">28.4.2.1 UDF Calling Sequences for Simple Functions</a></span></dt><dt><span class="section"><a href="extending-mysql.html#udf-aggr-calling">28.4.2.2 UDF Calling Sequences for Aggregate Functions</a></span></dt><dt><span class="section"><a href="extending-mysql.html#udf-arguments">28.4.2.3 UDF Argument Processing</a></span></dt><dt><span class="section"><a href="extending-mysql.html#udf-return-values">28.4.2.4 UDF Return Values and Error Handling</a></span></dt><dt><span class="section"><a href="extending-mysql.html#udf-compiling">28.4.2.5 UDF Compiling and Installing</a></span></dt><dt><span class="section"><a href="extending-mysql.html#udf-security">28.4.2.6 UDF Security Precautions</a></span></dt></dl>
</div>
<a class="indexterm" name="idm139899454406624"></a><a class="indexterm" name="idm139899454405168"></a><a class="indexterm" name="idm139899454403680"></a><p>
        For the UDF mechanism to work, functions must be written in C or
        C++ and your operating system must support dynamic loading.
        MySQL source distributions include a file
        <code class="filename">sql/udf_example.cc</code> that defines five UDF
        functions. Consult this file to see how UDF calling conventions
        work. The <code class="filename">include/mysql_com.h</code> header file
        defines UDF-related symbols and data structures, although you
        need not include this header file directly; it is included by
        <code class="filename">mysql.h</code>.
      </p><p>
        A UDF contains code that becomes part of the running server, so
        when you write a UDF, you are bound by any and all constraints
        that apply to writing server code. For example, you may have
        problems if you attempt to use functions from the
        <code class="literal">libstdc++</code> library. These constraints may
        change in future versions of the server, so it is possible that
        server upgrades will require revisions to UDFs that were
        originally written for older servers. For information about
        these constraints, see
        <a class="xref" href="installing.html#source-configuration-options" title="2.9.4 MySQL Source-Configuration Options">Section 2.9.4, “MySQL Source-Configuration Options”</a>, and
        <a class="xref" href="installing.html#compilation-problems" title="2.9.5 Dealing with Problems Compiling MySQL">Section 2.9.5, “Dealing with Problems Compiling MySQL”</a>.
      </p><p>
        To be able to use UDFs, you must link <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a>
        dynamically. If you want to use a UDF that needs to access
        symbols from <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> (for example, the
        <code class="literal">metaphone</code> function in
        <code class="filename">sql/udf_example.cc</code> uses
        <code class="literal">default_charset_info</code>), you must link the
        program with <code class="option">-rdynamic</code> (see <code class="literal">man
        dlopen</code>).
      </p><p>
        For each function that you want to use in SQL statements, you
        should define corresponding C (or C++) functions. In the
        following discussion, the name <span class="quote">“<span class="quote">xxx</span>”</span> is used for an
        example function name. To distinguish between SQL and C/C++
        usage, <code class="literal">XXX()</code> (uppercase) indicates an SQL
        function call, and <code class="literal">xxx()</code> (lowercase)
        indicates a C/C++ function call.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
          When using C++ you can encapsulate your C functions within:
        </p><pre class="programlisting">
extern "C" { ... }
</pre><p>
          This ensures that your C++ function names remain readable in
          the completed UDF.
</p>
</div>
<p>
        The following list describes the C/C++ functions that you write
        to implement the interface for a function named
        <code class="literal">XXX()</code>. The main function,
        <code class="literal">xxx()</code>, is required. In addition, a UDF
        requires at least one of the other functions described here, for
        reasons discussed in <a class="xref" href="extending-mysql.html#udf-security" title="28.4.2.6 UDF Security Precautions">Section 28.4.2.6, “UDF Security Precautions”</a>.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">xxx()</code>
          </p><p>
            The main function. This is where the function result is
            computed. The correspondence between the SQL function data
            type and the return type of your C/C++ function is shown
            here.
</p>
<div class="informaltable">
<a name="adding-udf-sql-c-cpp-data-types"></a><table summary="SQL function data types and corresponding C/C++ data types."><col width="25%"><col width="25%"><thead><tr>
                <th scope="col">SQL Type</th>
                <th scope="col">C/C++ Type</th>
              </tr></thead><tbody><tr>
                <td scope="row"><code class="literal">STRING</code></td>
                <td><code class="literal">char *</code></td>
              </tr><tr>
                <td scope="row"><a class="link" href="data-types.html#integer-types" title="11.2.1 Integer Types (Exact Value) - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT"><code class="literal">INTEGER</code></a></td>
                <td><code class="literal">long long</code></td>
              </tr><tr>
                <td scope="row"><a class="link" href="data-types.html#floating-point-types" title="11.2.3 Floating-Point Types (Approximate Value) - FLOAT, DOUBLE"><code class="literal">REAL</code></a></td>
                <td><code class="literal">double</code></td>
</tr></tbody></table>
</div>
<p>
            It is also possible to declare a
            <a class="link" href="data-types.html#fixed-point-types" title="11.2.2 Fixed-Point Types (Exact Value) - DECIMAL, NUMERIC"><code class="literal">DECIMAL</code></a> function, but
            currently the value is returned as a string, so you should
            write the UDF as though it were a <code class="literal">STRING</code>
            function. <code class="literal">ROW</code> functions are not
            implemented.
          </p></li><li class="listitem"><p>
            <code class="literal">xxx_init()</code>
          </p><p>
            The initialization function for <code class="literal">xxx()</code>. If
            present, it can be used for the following purposes:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                To check the number of arguments to
                <code class="literal">XXX()</code>.
              </p></li><li class="listitem"><p>
                To verify that the arguments are of a required type or,
                alternatively, to tell MySQL to coerce arguments to the
                required types when the main function is called.
              </p></li><li class="listitem"><p>
                To allocate any memory required by the main function.
              </p></li><li class="listitem"><p>
                To specify the maximum length of the result.
              </p></li><li class="listitem"><p>
                To specify (for <a class="link" href="data-types.html#floating-point-types" title="11.2.3 Floating-Point Types (Approximate Value) - FLOAT, DOUBLE"><code class="literal">REAL</code></a>
                functions) the maximum number of decimal places in the
                result.
              </p></li><li class="listitem"><p>
                To specify whether the result can be
                <code class="literal">NULL</code>.
</p></li></ul>
</div>
</li><li class="listitem"><p>
            <code class="literal">xxx_deinit()</code>
          </p><p>
            The deinitialization function for <code class="literal">xxx()</code>.
            If present, it should deallocate any memory allocated by the
            initialization function.
</p></li></ul>
</div>
<p>
        When an SQL statement invokes <code class="literal">XXX()</code>, MySQL
        calls the initialization function <code class="literal">xxx_init()</code>
        to let it perform any required setup, such as argument checking
        or memory allocation. If <code class="literal">xxx_init()</code> returns
        an error, MySQL aborts the SQL statement with an error message
        and does not call the main or deinitialization functions.
        Otherwise, MySQL calls the main function
        <code class="literal">xxx()</code> once for each row. After all rows have
        been processed, MySQL calls the deinitialization function
        <code class="literal">xxx_deinit()</code> so that it can perform any
        required cleanup.
      </p><p>
        For aggregate functions that work like
        <a class="link" href="functions.html#function_sum"><code class="literal">SUM()</code></a>, you must also provide the
        following functions:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">xxx_clear()</code>
          </p><p>
            Reset the current aggregate value but do not insert the
            argument as the initial aggregate value for a new group.
          </p></li><li class="listitem"><p>
            <code class="literal">xxx_add()</code>
          </p><p>
            Add the argument to the current aggregate value.
</p></li></ul>
</div>
<p>
        MySQL handles aggregate UDFs as follows:
</p>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
            Call <code class="literal">xxx_init()</code> to let the aggregate
            function allocate any memory it needs for storing results.
          </p></li><li class="listitem"><p>
            Sort the table according to the <code class="literal">GROUP BY</code>
            expression.
          </p></li><li class="listitem"><p>
            Call <code class="literal">xxx_clear()</code> for the first row in
            each new group.
          </p></li><li class="listitem"><p>
            Call <code class="literal">xxx_add()</code> for each row that belongs
            in the same group.
          </p></li><li class="listitem"><p>
            Call <code class="literal">xxx()</code> to get the result for the
            aggregate when the group changes or after the last row has
            been processed.
          </p></li><li class="listitem"><p>
            Repeat steps 3 to 5 until all rows has been processed
          </p></li><li class="listitem"><p>
            Call <code class="literal">xxx_deinit()</code> to let the UDF free any
            memory it has allocated.
</p></li></ol>
</div>
<p>
        All functions must be thread-safe. This includes not just the
        main function, but the initialization and deinitialization
        functions as well, and also the additional functions required by
        aggregate functions. A consequence of this requirement is that
        you are not permitted to allocate any global or static variables
        that change! If you need memory, you should allocate it in
        <code class="literal">xxx_init()</code> and free it in
        <code class="literal">xxx_deinit()</code>.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="udf-calling"></a>28.4.2.1 UDF Calling Sequences for Simple Functions</h4>
</div>
</div>
</div>
<a class="indexterm" name="idm139899454319840"></a><p>
          This section describes the different functions that you need
          to define when you create a simple UDF.
          <a class="xref" href="extending-mysql.html#adding-udf" title="28.4.2 Adding a New User-Defined Function">Section 28.4.2, “Adding a New User-Defined Function”</a>, describes the order in which
          MySQL calls these functions.
        </p><p>
          The main <code class="literal">xxx()</code> function should be declared
          as shown in this section. Note that the return type and
          parameters differ, depending on whether you declare the SQL
          function <code class="literal">XXX()</code> to return
          <code class="literal">STRING</code>,
          <a class="link" href="data-types.html#integer-types" title="11.2.1 Integer Types (Exact Value) - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT"><code class="literal">INTEGER</code></a>, or
          <a class="link" href="data-types.html#floating-point-types" title="11.2.3 Floating-Point Types (Approximate Value) - FLOAT, DOUBLE"><code class="literal">REAL</code></a> in the
          <a class="link" href="sql-syntax.html#create-function" title="13.1.13 CREATE FUNCTION Syntax"><code class="literal">CREATE FUNCTION</code></a> statement:
        </p><p>
          For <code class="literal">STRING</code> functions:
        </p><pre class="programlisting">
char *xxx(UDF_INIT *initid, UDF_ARGS *args,
          char *result, unsigned long *length,
          char *is_null, char *error);
</pre><p>
          For <a class="link" href="data-types.html#integer-types" title="11.2.1 Integer Types (Exact Value) - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT"><code class="literal">INTEGER</code></a> functions:
        </p><pre class="programlisting">
long long xxx(UDF_INIT *initid, UDF_ARGS *args,
              char *is_null, char *error);
</pre><p>
          For <a class="link" href="data-types.html#floating-point-types" title="11.2.3 Floating-Point Types (Approximate Value) - FLOAT, DOUBLE"><code class="literal">REAL</code></a> functions:
        </p><pre class="programlisting">
double xxx(UDF_INIT *initid, UDF_ARGS *args,
              char *is_null, char *error);
</pre><p>
          <a class="link" href="data-types.html#fixed-point-types" title="11.2.2 Fixed-Point Types (Exact Value) - DECIMAL, NUMERIC"><code class="literal">DECIMAL</code></a> functions return string
          values and should be declared the same way as
          <code class="literal">STRING</code> functions. <code class="literal">ROW</code>
          functions are not implemented.
        </p><p>
          The initialization and deinitialization functions are declared
          like this:
        </p><pre class="programlisting">
bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message);

void xxx_deinit(UDF_INIT *initid);
</pre><p>
          The <code class="literal">initid</code> parameter is passed to all three
          functions. It points to a <code class="literal">UDF_INIT</code>
          structure that is used to communicate information between
          functions. The <code class="literal">UDF_INIT</code> structure members
          follow. The initialization function should fill in any members
          that it wishes to change. (To use the default for a member,
          leave it unchanged.)
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              <code class="literal">bool maybe_null</code>
            </p><p>
              <code class="literal">xxx_init()</code> should set
              <code class="literal">maybe_null</code> to <code class="literal">1</code> if
              <code class="literal">xxx()</code> can return
              <code class="literal">NULL</code>. The default value is
              <code class="literal">1</code> if any of the arguments are declared
              <code class="literal">maybe_null</code>.
            </p></li><li class="listitem"><p>
              <code class="literal">unsigned int decimals</code>
            </p><p>
              The number of decimal digits to the right of the decimal
              point. The default value is the maximum number of decimal
              digits in the arguments passed to the main function. For
              example, if the function is passed
              <code class="literal">1.34</code>, <code class="literal">1.345</code>, and
              <code class="literal">1.3</code>, the default would be 3, because
              <code class="literal">1.345</code> has 3 decimal digits.
            </p><p>
              For arguments that have no fixed number of decimals, the
              <code class="literal">decimals</code> value is set to 31, which is 1
              more than the maximum number of decimals permitted for the
              <a class="link" href="data-types.html#fixed-point-types" title="11.2.2 Fixed-Point Types (Exact Value) - DECIMAL, NUMERIC"><code class="literal">DECIMAL</code></a>,
              <a class="link" href="data-types.html#floating-point-types" title="11.2.3 Floating-Point Types (Approximate Value) - FLOAT, DOUBLE"><code class="literal">FLOAT</code></a>, and
              <a class="link" href="data-types.html#floating-point-types" title="11.2.3 Floating-Point Types (Approximate Value) - FLOAT, DOUBLE"><code class="literal">DOUBLE</code></a> data types. This
              value is available as the constant
              <code class="literal">NOT_FIXED_DEC</code> in the
              <code class="filename">mysql_com.h</code> header file.
            </p><p>
              A <code class="literal">decimals</code> value of 31 is used for
              arguments in cases such as a
              <a class="link" href="data-types.html#floating-point-types" title="11.2.3 Floating-Point Types (Approximate Value) - FLOAT, DOUBLE"><code class="literal">FLOAT</code></a> or
              <a class="link" href="data-types.html#floating-point-types" title="11.2.3 Floating-Point Types (Approximate Value) - FLOAT, DOUBLE"><code class="literal">DOUBLE</code></a> column declared
              without an explicit number of decimals (for example,
              <a class="link" href="data-types.html#floating-point-types" title="11.2.3 Floating-Point Types (Approximate Value) - FLOAT, DOUBLE"><code class="literal">FLOAT</code></a> rather than
              <code class="literal">FLOAT(10,3)</code>) and for floating-point
              constants such as <code class="literal">1345E-3</code>. It is also
              used for string and other nonnumber arguments that might
              be converted within the function to numeric form.
            </p><p>
              The value to which the <code class="literal">decimals</code> member
              is initialized is only a default. It can be changed within
              the function to reflect the actual calculation performed.
              The default is determined such that the largest number of
              decimals of the arguments is used. If the number of
              decimals is <code class="literal">NOT_FIXED_DEC</code> for even one
              of the arguments, that is the value used for
              <code class="literal">decimals</code>.
            </p></li><li class="listitem"><p>
              <code class="literal">unsigned int max_length</code>
            </p><p>
              The maximum length of the result. The default
              <code class="literal">max_length</code> value differs depending on
              the result type of the function. For string functions, the
              default is the length of the longest argument. For integer
              functions, the default is 21 digits. For real functions,
              the default is 13 plus the number of decimal digits
              indicated by <code class="literal">initid-&gt;decimals</code>. (For
              numeric functions, the length includes any sign or decimal
              point characters.)
            </p><p>
              If you want to return a blob value, you can set
              <code class="literal">max_length</code> to 65KB or 16MB. This memory
              is not allocated, but the value is used to decide which
              data type to use if there is a need to temporarily store
              the data.
            </p></li><li class="listitem"><p>
              <code class="literal">char *ptr</code>
            </p><p>
              A pointer that the function can use for its own purposes.
              For example, functions can use
              <code class="literal">initid-&gt;ptr</code> to communicate allocated
              memory among themselves. <code class="literal">xxx_init()</code>
              should allocate the memory and assign it to this pointer:
            </p><pre class="programlisting">
initid-&gt;ptr = allocated_memory;
</pre><p>
              In <code class="literal">xxx()</code> and
              <code class="literal">xxx_deinit()</code>, refer to
              <code class="literal">initid-&gt;ptr</code> to use or deallocate the
              memory.
            </p></li><li class="listitem"><p>
              <code class="literal">bool const_item</code>
            </p><p>
              <code class="literal">xxx_init()</code> should set
              <code class="literal">const_item</code> to <code class="literal">1</code> if
              <code class="literal">xxx()</code> always returns the same value and
              to <code class="literal">0</code> otherwise.
</p></li></ul>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="udf-aggr-calling"></a>28.4.2.2 UDF Calling Sequences for Aggregate Functions</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm139899454249248"></a><p>
          This section describes the different functions that you need
          to define when you create an aggregate UDF.
          <a class="xref" href="extending-mysql.html#adding-udf" title="28.4.2 Adding a New User-Defined Function">Section 28.4.2, “Adding a New User-Defined Function”</a>, describes the order in which
          MySQL calls these functions.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              <code class="literal">xxx_reset()</code>
            </p><p>
              This function is called when MySQL finds the first row in
              a new group. It should reset any internal summary
              variables and then use the given
              <code class="literal">UDF_ARGS</code> argument as the first value in
              your internal summary value for the group. Declare
              <code class="literal">xxx_reset()</code> as follows:
            </p><pre class="programlisting">
void xxx_reset(UDF_INIT *initid, UDF_ARGS *args,
               char *is_null, char *error);
</pre><p>
              <code class="literal">xxx_reset()</code> is not needed or used in
              MySQL 8.0, in which the UDF interface uses
              <code class="literal">xxx_clear()</code> instead. However, you can
              define both <code class="literal">xxx_reset()</code> and
              <code class="literal">xxx_clear()</code> if you want to have your
              UDF work with older versions of the server. (If you do
              include both functions, the <code class="literal">xxx_reset()</code>
              function in many cases can be implemented internally by
              calling <code class="literal">xxx_clear()</code> to reset all
              variables, and then calling <code class="literal">xxx_add()</code>
              to add the <code class="literal">UDF_ARGS</code> argument as the
              first value in the group.)
            </p></li><li class="listitem"><p>
              <code class="literal">xxx_clear()</code>
            </p><p>
              This function is called when MySQL needs to reset the
              summary results. It is called at the beginning for each
              new group but can also be called to reset the values for a
              query where there were no matching rows. Declare
              <code class="literal">xxx_clear()</code> as follows:
            </p><pre class="programlisting">
void xxx_clear(UDF_INIT *initid, char *is_null, char *error);
</pre><p>
              <code class="literal">is_null</code> is set to point to
              <code class="literal">CHAR(0)</code> before calling
              <code class="literal">xxx_clear()</code>.
            </p><p>
              If something went wrong, you can store a value in the
              variable to which the <code class="literal">error</code> argument
              points. <code class="literal">error</code> points to a single-byte
              variable, not to a string buffer.
            </p><p>
              <code class="literal">xxx_clear()</code> is required by MySQL
              8.0.
            </p></li><li class="listitem"><p>
              <code class="literal">xxx_add()</code>
            </p><p>
              This function is called for all rows that belong to the
              same group. You should use it to add the value in the
              <code class="literal">UDF_ARGS</code> argument to your internal
              summary variable.
            </p><pre class="programlisting">
void xxx_add(UDF_INIT *initid, UDF_ARGS *args,
             char *is_null, char *error);
</pre></li></ul>
</div>
<p>
          The <code class="literal">xxx()</code> function for an aggregate UDF
          should be declared the same way as for a nonaggregate UDF. See
          <a class="xref" href="extending-mysql.html#udf-calling" title="28.4.2.1 UDF Calling Sequences for Simple Functions">Section 28.4.2.1, “UDF Calling Sequences for Simple Functions”</a>.
        </p><p>
          For an aggregate UDF, MySQL calls the <code class="literal">xxx()</code>
          function after all rows in the group have been processed. You
          should normally never access its <code class="literal">UDF_ARGS</code>
          argument here but instead return a value based on your
          internal summary variables.
        </p><p>
          Return value handling in <code class="literal">xxx()</code> should be
          done the same way as for a nonaggregate UDF. See
          <a class="xref" href="extending-mysql.html#udf-return-values" title="28.4.2.4 UDF Return Values and Error Handling">Section 28.4.2.4, “UDF Return Values and Error Handling”</a>.
        </p><p>
          The <code class="literal">xxx_reset()</code> and
          <code class="literal">xxx_add()</code> functions handle their
          <code class="literal">UDF_ARGS</code> argument the same way as functions
          for nonaggregate UDFs. See <a class="xref" href="extending-mysql.html#udf-arguments" title="28.4.2.3 UDF Argument Processing">Section 28.4.2.3, “UDF Argument Processing”</a>.
        </p><p>
          The pointer arguments to <code class="literal">is_null</code> and
          <code class="literal">error</code> are the same for all calls to
          <code class="literal">xxx_reset()</code>,
          <code class="literal">xxx_clear()</code>, <code class="literal">xxx_add()</code>
          and <code class="literal">xxx()</code>. You can use this to remember
          that you got an error or whether the <code class="literal">xxx()</code>
          function should return <code class="literal">NULL</code>. You should not
          store a string into <code class="literal">*error</code>!
          <code class="literal">error</code> points to a single-byte variable, not
          to a string buffer.
        </p><p>
          <code class="literal">*is_null</code> is reset for each group (before
          calling <code class="literal">xxx_clear()</code>).
          <code class="literal">*error</code> is never reset.
        </p><p>
          If <code class="literal">*is_null</code> or <code class="literal">*error</code>
          are set when <code class="literal">xxx()</code> returns, MySQL returns
          <code class="literal">NULL</code> as the result for the group function.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="udf-arguments"></a>28.4.2.3 UDF Argument Processing</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm139899454197664"></a><a class="indexterm" name="idm139899454196592"></a><p>
          The <code class="literal">args</code> parameter points to a
          <code class="literal">UDF_ARGS</code> structure that has the members
          listed here:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              <code class="literal">unsigned int arg_count</code>
            </p><p>
              The number of arguments. Check this value in the
              initialization function if you require your function to be
              called with a particular number of arguments. For example:
            </p><pre class="programlisting">
if (args-&gt;arg_count != 2)
{
    strcpy(message,"XXX() requires two arguments");
    return 1;
}
</pre><p>
              For other <code class="literal">UDF_ARGS</code> member values that
              are arrays, array references are zero-based. That is,
              refer to array members using index values from 0 to
              <code class="literal">args-&gt;arg_count</code> − 1.
            </p></li><li class="listitem"><p>
              <code class="literal">enum Item_result *arg_type</code>
            </p><p>
              A pointer to an array containing the types for each
              argument. The possible type values are
              <code class="literal">STRING_RESULT</code>,
              <code class="literal">INT_RESULT</code>,
              <code class="literal">REAL_RESULT</code>, and
              <code class="literal">DECIMAL_RESULT</code>.
            </p><p>
              To make sure that arguments are of a given type and return
              an error if they are not, check the
              <code class="literal">arg_type</code> array in the initialization
              function. For example:
            </p><pre class="programlisting">
if (args-&gt;arg_type[0] != STRING_RESULT ||
    args-&gt;arg_type[1] != INT_RESULT)
{
    strcpy(message,"XXX() requires a string and an integer");
    return 1;
}
</pre><p>
              Arguments of type <code class="literal">DECIMAL_RESULT</code> are
              passed as strings, so you should handle them the same way
              as <code class="literal">STRING_RESULT</code> values.
            </p><p>
              As an alternative to requiring your function's arguments
              to be of particular types, you can use the initialization
              function to set the <code class="literal">arg_type</code> elements
              to the types you want. This causes MySQL to coerce
              arguments to those types for each call to
              <code class="literal">xxx()</code>. For example, to specify that the
              first two arguments should be coerced to string and
              integer, respectively, do this in
              <code class="literal">xxx_init()</code>:
            </p><pre class="programlisting">
args-&gt;arg_type[0] = STRING_RESULT;
args-&gt;arg_type[1] = INT_RESULT;
</pre><p>
              Exact-value decimal arguments such as
              <code class="literal">1.3</code> or
              <a class="link" href="data-types.html#fixed-point-types" title="11.2.2 Fixed-Point Types (Exact Value) - DECIMAL, NUMERIC"><code class="literal">DECIMAL</code></a> column values are
              passed with a type of <code class="literal">DECIMAL_RESULT</code>.
              However, the values are passed as strings. If you want to
              receive a number, use the initialization function to
              specify that the argument should be coerced to a
              <code class="literal">REAL_RESULT</code> value:
            </p><pre class="programlisting">
args-&gt;arg_type[2] = REAL_RESULT;
</pre></li><li class="listitem"><p>
              <code class="literal">char **args</code>
            </p><p>
              <code class="literal">args-&gt;args</code> communicates information
              to the initialization function about the general nature of
              the arguments passed to your function. For a constant
              argument <code class="literal">i</code>,
              <code class="literal">args-&gt;args[i]</code> points to the argument
              value. (See later for instructions on how to access the
              value properly.) For a nonconstant argument,
              <code class="literal">args-&gt;args[i]</code> is
              <code class="literal">0</code>. A constant argument is an expression
              that uses only constants, such as <code class="literal">3</code> or
              <code class="literal">4*7-2</code> or
              <a class="link" href="functions.html#function_sin"><code class="literal">SIN(3.14)</code></a>. A nonconstant
              argument is an expression that refers to values that may
              change from row to row, such as column names or functions
              that are called with nonconstant arguments.
            </p><p>
              For each invocation of the main function,
              <code class="literal">args-&gt;args</code> contains the actual
              arguments that are passed for the row currently being
              processed.
            </p><p>
              If argument <code class="literal">i</code> represents
              <code class="literal">NULL</code>,
              <code class="literal">args-&gt;args[i]</code> is a null pointer (0).
              If the argument is not <code class="literal">NULL</code>, functions
              can refer to it as follows:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                  An argument of type <code class="literal">STRING_RESULT</code>
                  is given as a string pointer plus a length, to enable
                  handling of binary data or data of arbitrary length.
                  The string contents are available as
                  <code class="literal">args-&gt;args[i]</code> and the string
                  length is <code class="literal">args-&gt;lengths[i]</code>. Do
                  not assume that the string is null-terminated.
                </p></li><li class="listitem"><p>
                  For an argument of type <code class="literal">INT_RESULT</code>,
                  you must cast <code class="literal">args-&gt;args[i]</code> to a
                  <code class="literal">long long</code> value:
                </p><pre class="programlisting">
long long int_val;
int_val = *((long long*) args-&gt;args[i]);
</pre></li><li class="listitem"><p>
                  For an argument of type
                  <code class="literal">REAL_RESULT</code>, you must cast
                  <code class="literal">args-&gt;args[i]</code> to a
                  <code class="literal">double</code> value:
                </p><pre class="programlisting">
double    real_val;
real_val = *((double*) args-&gt;args[i]);
</pre></li><li class="listitem"><p>
                  For an argument of type
                  <code class="literal">DECIMAL_RESULT</code>, the value is passed
                  as a string and should be handled like a
                  <code class="literal">STRING_RESULT</code> value.
                </p></li><li class="listitem"><p>
                  <code class="literal">ROW_RESULT</code> arguments are not
                  implemented.
</p></li></ul>
</div>
</li><li class="listitem"><p>
              <code class="literal">unsigned long *lengths</code>
            </p><p>
              For the initialization function, the
              <code class="literal">lengths</code> array indicates the maximum
              string length for each argument. You should not change
              these. For each invocation of the main function,
              <code class="literal">lengths</code> contains the actual lengths of
              any string arguments that are passed for the row currently
              being processed. For arguments of types
              <code class="literal">INT_RESULT</code> or
              <code class="literal">REAL_RESULT</code>, <code class="literal">lengths</code>
              still contains the maximum length of the argument (as for
              the initialization function).
            </p></li><li class="listitem"><p>
              <code class="literal">char *maybe_null</code>
            </p><p>
              For the initialization function, the
              <code class="literal">maybe_null</code> array indicates for each
              argument whether the argument value might be null (0 if
              no, 1 if yes).
            </p></li><li class="listitem"><p>
              <code class="literal">char **attributes</code>
            </p><p>
              <code class="literal">args-&gt;attributes</code> communicates
              information about the names of the UDF arguments. For
              argument <code class="literal">i</code>, the attribute name is
              available as a string in
              <code class="literal">args-&gt;attributes[i]</code> and the
              attribute length is
              <code class="literal">args-&gt;attribute_lengths[i]</code>. Do not
              assume that the string is null-terminated.
            </p><p>
              By default, the name of a UDF argument is the text of the
              expression used to specify the argument. For UDFs, an
              argument may also have an optional <code class="literal">[AS]
              <em class="replaceable"><code>alias_name</code></em></code> clause, in
              which case the argument name is
              <em class="replaceable"><code>alias_name</code></em>. The
              <code class="literal">attributes</code> value for each argument thus
              depends on whether an alias was given.
            </p><p>
              Suppose that a UDF <code class="literal">my_udf()</code> is invoked
              as follows:
            </p><pre class="programlisting">
SELECT my_udf(expr1, expr2 AS alias1, expr3 alias2);
</pre><p>
              In this case, the <code class="literal">attributes</code> and
              <code class="literal">attribute_lengths</code> arrays will have
              these values:
            </p><pre class="programlisting">
args-&gt;attributes[0] = "expr1"
args-&gt;attribute_lengths[0] = 5

args-&gt;attributes[1] = "alias1"
args-&gt;attribute_lengths[1] = 6

args-&gt;attributes[2] = "alias2"
args-&gt;attribute_lengths[2] = 6
</pre></li><li class="listitem"><p>
              <code class="literal">unsigned long *attribute_lengths</code>
            </p><p>
              The <code class="literal">attribute_lengths</code> array indicates
              the length of each argument name.
</p></li></ul>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="udf-return-values"></a>28.4.2.4 UDF Return Values and Error Handling</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm139899454115984"></a><a class="indexterm" name="idm139899454114528"></a><a class="indexterm" name="idm139899454113040"></a><a class="indexterm" name="idm139899454111552"></a><p>
          The initialization function should return <code class="literal">0</code>
          if no error occurred and <code class="literal">1</code> otherwise. If an
          error occurs, <code class="literal">xxx_init()</code> should store a
          null-terminated error message in the
          <code class="literal">message</code> parameter. The message is returned
          to the client. The message buffer is
          <code class="literal">MYSQL_ERRMSG_SIZE</code> characters long, but you
          should try to keep the message to less than 80 characters so
          that it fits the width of a standard terminal screen.
        </p><p>
          The return value of the main function <code class="literal">xxx()</code>
          is the function value, for <code class="literal">long long</code> and
          <code class="literal">double</code> functions. A string function should
          return a pointer to the result and set
          <code class="literal">*length</code> to the length (in bytes) of the
          return value. For example:
        </p><pre class="programlisting">
memcpy(result, "result string", 13);
*length = 13;
</pre><p>
          MySQL passes a buffer to the <code class="literal">xxx()</code> function
          using the <code class="literal">result</code> parameter. This buffer is
          sufficiently long to hold 255 characters, which can be
          multibyte characters. The <code class="literal">xxx()</code> function
          can store the result in this buffer if it fits, in which case
          the return value should be a pointer to the buffer. If the
          function stores the result in a different buffer, it should
          return a pointer to that buffer.
        </p><p>
          If your string function does not use the supplied buffer (for
          example, if it needs to return a string longer than 255
          characters), you must allocate the space for your own buffer
          with <code class="literal">malloc()</code> in your
          <code class="literal">xxx_init()</code> function or your
          <code class="literal">xxx()</code> function and free it in your
          <code class="literal">xxx_deinit()</code> function. You can store the
          allocated memory in the <code class="literal">ptr</code> slot in the
          <code class="literal">UDF_INIT</code> structure for reuse by future
          <code class="literal">xxx()</code> calls. See
          <a class="xref" href="extending-mysql.html#udf-calling" title="28.4.2.1 UDF Calling Sequences for Simple Functions">Section 28.4.2.1, “UDF Calling Sequences for Simple Functions”</a>.
        </p><p>
          To indicate a return value of <code class="literal">NULL</code> in the
          main function, set <code class="literal">*is_null</code> to
          <code class="literal">1</code>:
        </p><pre class="programlisting">
*is_null = 1;
</pre><p>
          To indicate an error return in the main function, set
          <code class="literal">*error</code> to <code class="literal">1</code>:
        </p><pre class="programlisting">
*error = 1;
</pre><p>
          If <code class="literal">xxx()</code> sets <code class="literal">*error</code> to
          <code class="literal">1</code> for any row, the function value is
          <code class="literal">NULL</code> for the current row and for any
          subsequent rows processed by the statement in which
          <code class="literal">XXX()</code> was invoked.
          (<code class="literal">xxx()</code> is not even called for subsequent
          rows.)
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="udf-compiling"></a>28.4.2.5 UDF Compiling and Installing</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm139899454080128"></a><a class="indexterm" name="idm139899454078672"></a><a class="indexterm" name="idm139899454077184"></a><p>
          Files implementing UDFs must be compiled and installed on the
          host where the server runs. This process is described below
          for the example UDF file
          <code class="filename">sql/udf_example.cc</code> that is included in
          MySQL source distributions.
        </p><p>
          If a UDF will be referred to in statements that will be
          replicated to slave servers, you must ensure that every slave
          also has the function available. Otherwise, replication will
          fail on the slaves when they attempt to invoke the function.
        </p><p>
          The immediately following instructions are for Unix.
          Instructions for Windows are given later in this section.
        </p><p>
          The <code class="filename">udf_example.cc</code> file contains the
          following functions:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              <code class="literal">metaphon()</code> returns a metaphon string of
              the string argument. This is something like a soundex
              string, but it is more tuned for English.
            </p></li><li class="listitem"><p>
              <code class="literal">myfunc_double()</code> returns the sum of the
              ASCII values of the characters in its arguments, divided
              by the sum of the length of its arguments.
            </p></li><li class="listitem"><p>
              <code class="literal">myfunc_int()</code> returns the sum of the
              length of its arguments.
            </p></li><li class="listitem"><p>
              <code class="literal">sequence([const int])</code> returns a
              sequence starting from the given number or 1 if no number
              has been given.
            </p></li><li class="listitem"><p>
              <code class="literal">lookup()</code> returns the IP address for a
              host name.
            </p></li><li class="listitem"><p>
              <code class="literal">reverse_lookup()</code> returns the host name
              for an IP address. The function may be called either with
              a single string argument of the form
              <code class="literal">'xxx.xxx.xxx.xxx'</code> or with four numbers.
            </p></li><li class="listitem"><p>
              <code class="literal">avgcost()</code> returns an average cost. This
              is an aggregate function.
</p></li></ul>
</div>
<p>
          A dynamically loadable file should be compiled as a sharable
          library file, using a command something like this:
        </p><pre class="programlisting">
shell&gt; <strong class="userinput"><code>gcc -shared -o udf_example.so udf_example.cc</code></strong>
</pre><p>
          If you are using <span class="command"><strong>gcc</strong></span> with
          <span class="command"><strong>CMake</strong></span> (which is how MySQL is configured),
          you should be able to create
          <code class="filename">udf_example.so</code> with a simpler command:
        </p><pre class="programlisting">
shell&gt; <strong class="userinput"><code>make udf_example</code></strong>
</pre><p>
          After you compile a shared object containing UDFs, you must
          install it and tell MySQL about it. Compiling a shared object
          from <code class="filename">udf_example.cc</code> using
          <span class="command"><strong>gcc</strong></span> directly produces a file named
          <code class="filename">udf_example.so</code>. Copy the shared object to
          the server's plugin directory and name it
          <code class="filename">udf_example.so</code>. This directory is given
          by the value of the
          <a class="link" href="server-administration.html#sysvar_plugin_dir"><code class="literal">plugin_dir</code></a> system variable.
        </p><p>
          On some systems, the <span class="command"><strong>ldconfig</strong></span> program that
          configures the dynamic linker does not recognize a shared
          object unless its name begins with <code class="literal">lib</code>. In
          this case you should rename a file such as
          <code class="filename">udf_example.so</code> to
          <code class="filename">libudf_example.so</code>.
        </p><p>
          On Windows, you can compile user-defined functions by using
          the following procedure:
</p>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
              Obtain a MySQL source distribution. See
              <a class="xref" href="installing.html#getting-mysql" title="2.1.2 How to Get MySQL">Section 2.1.2, “How to Get MySQL”</a>.
            </p></li><li class="listitem"><p>
              Obtain the <span class="command"><strong>CMake</strong></span> build utility, if
              necessary, from <a class="ulink" href="http://www.cmake.org" target="_top">http://www.cmake.org</a>.
              (Version 2.6 or later is required).
            </p></li><li class="listitem"><p>
              In the source tree, look in the <code class="filename">sql</code>
              directory. There are files named
              <code class="filename">udf_example.def</code>
              <code class="filename">udf_example.cc</code> there. Copy both files
              from this directory to your working directory.
            </p></li><li class="listitem"><p>
              Create a <span class="command"><strong>CMake</strong></span>
              <code class="filename">makefile</code>
              (<code class="filename">CMakeLists.txt</code>) with these contents:
            </p><pre class="programlisting">
PROJECT(udf_example)

# Path for MySQL include directory
INCLUDE_DIRECTORIES("c:/mysql/include")

ADD_DEFINITIONS("-DHAVE_DLOPEN")
ADD_LIBRARY(udf_example MODULE udf_example.cc udf_example.def)
TARGET_LINK_LIBRARIES(udf_example wsock32)
</pre></li><li class="listitem"><p>
              Create the VC project and solution files:
            </p><pre class="programlisting">
cmake -G "&lt;Generator&gt;"
</pre><p>
              Invoking <span class="command"><strong>cmake --help</strong></span> shows you a list
              of valid Generators.
            </p></li><li class="listitem"><p>
              Create <code class="filename">udf_example.dll</code>:
            </p><pre class="programlisting">
devenv udf_example.sln /build Release
</pre></li></ol>
</div>
<p>
          After the shared library file has been installed, notify
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> about the new functions with the
          following statements. If library files have a suffix different
          from <code class="filename">.so</code> on your system, substitute the
          correct suffix throughout (for example,
          <code class="filename">.dll</code> on Windows).
        </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>CREATE FUNCTION metaphon RETURNS STRING SONAME 'udf_example.so';</code></strong>
mysql&gt; <strong class="userinput"><code>CREATE FUNCTION myfunc_double RETURNS REAL SONAME 'udf_example.so';</code></strong>
mysql&gt; <strong class="userinput"><code>CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME 'udf_example.so';</code></strong>
mysql&gt; <strong class="userinput"><code>CREATE FUNCTION sequence RETURNS INTEGER SONAME 'udf_example.so';</code></strong>
mysql&gt; <strong class="userinput"><code>CREATE FUNCTION lookup RETURNS STRING SONAME 'udf_example.so';</code></strong>
mysql&gt; <strong class="userinput"><code>CREATE FUNCTION reverse_lookup</code></strong>
    -&gt;        <strong class="userinput"><code>RETURNS STRING SONAME 'udf_example.so';</code></strong>
mysql&gt; <strong class="userinput"><code>CREATE AGGREGATE FUNCTION avgcost</code></strong>
    -&gt;        <strong class="userinput"><code>RETURNS REAL SONAME 'udf_example.so';</code></strong>
</pre><p>
          Once installed, a function remains installed until it is
          uninstalled.
        </p><p>
          To delete functions, use <a class="link" href="sql-syntax.html#drop-function" title="13.1.24 DROP FUNCTION Syntax"><code class="literal">DROP
          FUNCTION</code></a>:
        </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>DROP FUNCTION metaphon;</code></strong>
mysql&gt; <strong class="userinput"><code>DROP FUNCTION myfunc_double;</code></strong>
mysql&gt; <strong class="userinput"><code>DROP FUNCTION myfunc_int;</code></strong>
mysql&gt; <strong class="userinput"><code>DROP FUNCTION sequence;</code></strong>
mysql&gt; <strong class="userinput"><code>DROP FUNCTION lookup;</code></strong>
mysql&gt; <strong class="userinput"><code>DROP FUNCTION reverse_lookup;</code></strong>
mysql&gt; <strong class="userinput"><code>DROP FUNCTION avgcost;</code></strong>
</pre><p>
          The <a class="link" href="sql-syntax.html#create-function" title="13.1.13 CREATE FUNCTION Syntax"><code class="literal">CREATE FUNCTION</code></a> and
          <a class="link" href="sql-syntax.html#drop-function" title="13.1.24 DROP FUNCTION Syntax"><code class="literal">DROP FUNCTION</code></a> statements update
          the <code class="literal">func</code> system table in the
          <code class="literal">mysql</code> database. The function's name, type
          and shared library name are saved in the table. You must have
          the <a class="link" href="security.html#priv_insert"><code class="literal">INSERT</code></a> or
          <a class="link" href="security.html#priv_delete"><code class="literal">DELETE</code></a> privilege for the
          <code class="literal">mysql</code> database to create or drop functions,
          respectively.
        </p><p>
          You should not use <a class="link" href="sql-syntax.html#create-function" title="13.1.13 CREATE FUNCTION Syntax"><code class="literal">CREATE
          FUNCTION</code></a> to add a function that has previously been
          created. If you need to reinstall a function, you should
          remove it with <a class="link" href="sql-syntax.html#drop-function" title="13.1.24 DROP FUNCTION Syntax"><code class="literal">DROP FUNCTION</code></a>
          and then reinstall it with <a class="link" href="sql-syntax.html#create-function" title="13.1.13 CREATE FUNCTION Syntax"><code class="literal">CREATE
          FUNCTION</code></a>. You would need to do this, for example, if
          you recompile a new version of your function, so that
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> gets the new version. Otherwise, the
          server continues to use the old version.
        </p><p>
          An active function is one that has been loaded with
          <a class="link" href="sql-syntax.html#create-function" title="13.1.13 CREATE FUNCTION Syntax"><code class="literal">CREATE FUNCTION</code></a> and not removed
          with <a class="link" href="sql-syntax.html#drop-function" title="13.1.24 DROP FUNCTION Syntax"><code class="literal">DROP FUNCTION</code></a>. All active
          functions are reloaded each time the server starts, unless you
          start <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> with the
          <a class="link" href="server-administration.html#option_mysqld_skip-grant-tables"><code class="option">--skip-grant-tables</code></a> option. In
          this case, UDF initialization is skipped and UDFs are
          unavailable.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="udf-security"></a>28.4.2.6 UDF Security Precautions</h4>

</div>

</div>

</div>
<p>
          MySQL takes several measures to prevent misuse of user-defined
          functions.
        </p><p>
          UDF library files cannot be placed in arbitrary directories.
          They must be located in the server's plugin directory. This
          directory is given by the value of the
          <a class="link" href="server-administration.html#sysvar_plugin_dir"><code class="literal">plugin_dir</code></a> system variable.
        </p><p>
          To use <a class="link" href="sql-syntax.html#create-function" title="13.1.13 CREATE FUNCTION Syntax"><code class="literal">CREATE FUNCTION</code></a> or
          <a class="link" href="sql-syntax.html#drop-function" title="13.1.24 DROP FUNCTION Syntax"><code class="literal">DROP FUNCTION</code></a>, you must have
          the <a class="link" href="security.html#priv_insert"><code class="literal">INSERT</code></a> or
          <a class="link" href="security.html#priv_delete"><code class="literal">DELETE</code></a> privilege, respectively,
          for the <code class="literal">mysql</code> database. This is necessary
          because those statements add and delete rows from the
          <code class="literal">mysql.func</code> table.
        </p><p>
          UDFs should have at least one symbol defined in addition to
          the <code class="literal">xxx</code> symbol that corresponds to the main
          <code class="literal">xxx()</code> function. These auxiliary symbols
          correspond to the <code class="literal">xxx_init()</code>,
          <code class="literal">xxx_deinit()</code>,
          <code class="literal">xxx_reset()</code>,
          <code class="literal">xxx_clear()</code>, and
          <code class="literal">xxx_add()</code> functions.
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> also supports an
          <a class="link" href="server-administration.html#option_mysqld_allow-suspicious-udfs"><code class="option">--allow-suspicious-udfs</code></a> option
          that controls whether UDFs that have only an
          <code class="literal">xxx</code> symbol can be loaded. By default, the
          option is off, to prevent attempts at loading functions from
          shared library files other than those containing legitimate
          UDFs. If you have older UDFs that contain only the
          <code class="literal">xxx</code> symbol and that cannot be recompiled to
          include an auxiliary symbol, it may be necessary to specify
          the <a class="link" href="server-administration.html#option_mysqld_allow-suspicious-udfs"><code class="option">--allow-suspicious-udfs</code></a>
          option. Otherwise, you should avoid enabling this capability.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="adding-native-function"></a>28.4.3 Adding a New Native Function</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm139899453968400"></a><a class="indexterm" name="idm139899453966944"></a><a class="indexterm" name="idm139899453965456"></a><p>
        To add a new native MySQL function, use the procedure described
        here, which requires that you use a source distribution. You
        cannot add native functions to a binary distribution because it
        is necessary to modify MySQL source code and compile MySQL from
        the modified source. If you migrate to another version of MySQL
        (for example, when a new version is released), you must repeat
        the procedure with the new version.
      </p><p>
        If the new native function will be referred to in statements
        that will be replicated to slave servers, you must ensure that
        every slave server also has the function available. Otherwise,
        replication will fail on the slaves when they attempt to invoke
        the function.
      </p><p>
        To add a new native function, follow these steps to modify
        source files in the <code class="filename">sql</code> directory:
</p>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
            Create a subclass for the function in
            <code class="filename">item_create.cc</code>:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                If the function takes a fixed number of arguments,
                create a subclass of
                <code class="literal">Create_func_arg0</code>,
                <code class="literal">Create_func_arg1</code>,
                <code class="literal">Create_func_arg2</code>, or
                <code class="literal">Create_func_arg3</code>, respectively,
                depending on whether the function takes zero, one, two,
                or three arguments. For examples, see the
                <code class="literal">Create_func_uuid</code>,
                <code class="literal">Create_func_abs</code>,
                <code class="literal">Create_func_pow</code>, and
                <code class="literal">Create_func_lpad</code> classes.
              </p></li><li class="listitem"><p>
                If the function takes a variable number of arguments,
                create a subclass of
                <code class="literal">Create_native_func</code>. For an example,
                see <code class="literal">Create_func_concat</code>.
</p></li></ul>
</div>
</li><li class="listitem"><p>
            To provide a name by which the function can be referred to
            in SQL statements, register the name in
            <code class="filename">item_create.cc</code> by adding a line to this
            array:
          </p><pre class="programlisting">
static Native_func_registry func_array[]
</pre><p>
            You can register several names for the same function. For
            example, see the lines for <code class="literal">"LCASE"</code> and
            <code class="literal">"LOWER"</code>, which are aliases for
            <code class="literal">Create_func_lcase</code>.
          </p></li><li class="listitem"><p>
            In <code class="filename">item_func.h</code>, declare a class
            inheriting from <code class="literal">Item_num_func</code> or
            <code class="literal">Item_str_func</code>, depending on whether your
            function returns a number or a string.
          </p></li><li class="listitem"><p>
            In <code class="filename">item_func.cc</code>, add one of the
            following declarations, depending on whether you are
            defining a numeric or string function:
          </p><pre class="programlisting">
double   Item_func_newname::val()
longlong Item_func_newname::val_int()
String  *Item_func_newname::Str(String *str)
</pre><p>
            If you inherit your object from any of the standard items
            (like <code class="literal">Item_num_func</code>), you probably only
            have to define one of these functions and let the parent
            object take care of the other functions. For example, the
            <code class="literal">Item_str_func</code> class defines a
            <code class="literal">val()</code> function that executes
            <code class="literal">atof()</code> on the value returned by
            <code class="literal">::str()</code>.
          </p></li><li class="listitem"><p>
            If the function is nondeterministic, include the following
            statement in the item constructor to indicate that function
            results should not be cached:
          </p><pre class="programlisting">
current_thd-&gt;lex-&gt;safe_to_cache_query=0;
</pre><p>
            A function is nondeterministic if, given fixed values for
            its arguments, it can return different results for different
            invocations.
          </p></li><li class="listitem"><p>
            You should probably also define the following object
            function:
          </p><pre class="programlisting">
void Item_func_newname::fix_length_and_dec()
</pre><p>
            This function should at least calculate
            <code class="literal">max_length</code> based on the given arguments.
            <code class="literal">max_length</code> is the maximum number of
            characters the function may return. This function should
            also set <code class="literal">maybe_null = 0</code> if the main
            function cannot return a <code class="literal">NULL</code> value. The
            function can check whether any of the function arguments can
            return <code class="literal">NULL</code> by checking the arguments'
            <code class="literal">maybe_null</code> variable. Look at
            <code class="literal">Item_func_mod::fix_length_and_dec</code> for a
            typical example of how to do this.
</p></li></ol>
</div>
<p>
        All functions must be thread-safe. In other words, do not use
        any global or static variables in the functions without
        protecting them with mutexes.
      </p><p>
        If you want to return <code class="literal">NULL</code> from
        <code class="literal">::val()</code>, <code class="literal">::val_int()</code>, or
        <code class="literal">::str()</code>, you should set
        <code class="literal">null_value</code> to 1 and return 0.
      </p><p>
        For <code class="literal">::str()</code> object functions, there are
        additional considerations to be aware of:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            The <code class="literal">String *str</code> argument provides a
            string buffer that may be used to hold the result. (For more
            information about the <code class="literal">String</code> type, take a
            look at the <code class="filename">sql_string.h</code> file.)
          </p></li><li class="listitem"><p>
            The <code class="literal">::str()</code> function should return the
            string that holds the result, or <code class="literal">(char*)
            0</code> if the result is <code class="literal">NULL</code>.
          </p></li><li class="listitem"><p>
            All current string functions try to avoid allocating any
            memory unless absolutely necessary!
</p></li></ul>
</div>

</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="porting"></a>28.5 Debugging and Porting MySQL</h2>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="extending-mysql.html#debugging-server">28.5.1 Debugging a MySQL Server</a></span></dt><dt><span class="section"><a href="extending-mysql.html#debugging-client">28.5.2 Debugging a MySQL Client</a></span></dt><dt><span class="section"><a href="extending-mysql.html#dbug-package">28.5.3 The DBUG Package</a></span></dt></dl>
</div>
<a class="indexterm" name="idm139899453909360"></a><p>
      This section helps you port MySQL to other operating systems. Do
      check the list of currently supported operating systems first. See
      <a class="ulink" href="http://www.mysql.com/support/supportedplatforms/database.html" target="_top">http://www.mysql.com/support/supportedplatforms/database.html</a>. If you have created a
      new port of MySQL, please let us know so that we can list it here
      and on our website (<a class="ulink" href="http://www.mysql.com/" target="_top">http://www.mysql.com/</a>),
      recommending it to other users.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
        If you create a new port of MySQL, you are free to copy and
        distribute it under the GPL license, but it does not make you a
        copyright holder of MySQL.
</p>
</div>
<p>
      A working POSIX thread library is needed for the server.
    </p><p>
      To build MySQL from source, your system must satisfy the tool
      requirements listed at <a class="xref" href="installing.html#source-installation" title="2.9 Installing MySQL from Source">Section 2.9, “Installing MySQL from Source”</a>.
    </p><p>
      If you run into problems with a new port, you may have to do some
      debugging of MySQL! See <a class="xref" href="extending-mysql.html#debugging-server" title="28.5.1 Debugging a MySQL Server">Section 28.5.1, “Debugging a MySQL Server”</a>.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
        Before you start debugging <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a>, first get
        the test program <code class="literal">mysys/thr_lock</code> to work. This
        ensures that your thread installation has even a remote chance
        to work!
</p>
</div>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
<div class="admon-title">
Note
</div>
<p>
        The MySQL source code contains internal documentation written
        using Doxygen. This documentation is useful for understanding
        how MySQL works from a developer perspective. The generated
        Doxygen content is available at
        <a class="ulink" href="http://dev.mysql.com/doc/dev/mysql-server/latest/" target="_top">http://dev.mysql.com/doc/dev/mysql-server/latest/</a>. It is also
        possible to generate this content locally from a MySQL source
        distribution using the instructions at
        <a class="xref" href="installing.html#source-installation-doxygen" title="2.9.7 Generating MySQL Doxygen Documentation Content">Section 2.9.7, “Generating MySQL Doxygen Documentation Content”</a>.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="debugging-server"></a>28.5.1 Debugging a MySQL Server</h3>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="extending-mysql.html#compiling-for-debugging">28.5.1.1 Compiling MySQL for Debugging</a></span></dt><dt><span class="section"><a href="extending-mysql.html#making-trace-files">28.5.1.2 Creating Trace Files</a></span></dt><dt><span class="section"><a href="extending-mysql.html#making-windows-dumps">28.5.1.3 Using WER with PDB to create a Windows crashdump</a></span></dt><dt><span class="section"><a href="extending-mysql.html#using-gdb-on-mysqld">28.5.1.4 Debugging mysqld under gdb</a></span></dt><dt><span class="section"><a href="extending-mysql.html#using-stack-trace">28.5.1.5 Using a Stack Trace</a></span></dt><dt><span class="section"><a href="extending-mysql.html#using-log-files">28.5.1.6 Using Server Logs to Find Causes of Errors in mysqld</a></span></dt><dt><span class="section"><a href="extending-mysql.html#reproducible-test-case">28.5.1.7 Making a Test Case If You Experience Table Corruption</a></span></dt></dl>
</div>
<a class="indexterm" name="idm139899453895728"></a><a class="indexterm" name="idm139899453894272"></a><a class="indexterm" name="idm139899453892784"></a><p>
        If you are using some functionality that is very new in MySQL,
        you can try to run <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> with the
        <code class="option">--skip-new</code> (which disables all new, potentially
        unsafe functionality). See <a class="xref" href="error-handling.html#crashing" title="B.5.3.3 What to Do If MySQL Keeps Crashing">Section B.5.3.3, “What to Do If MySQL Keeps Crashing”</a>.
      </p><p>
        If <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> does not want to start, verify that
        you have no <code class="filename">my.cnf</code> files that interfere
        with your setup! You can check your <code class="filename">my.cnf</code>
        arguments with <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld --print-defaults</strong></span></a> and
        avoid using them by starting with <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld --no-defaults
        ...</strong></span></a>.
      </p><p>
        If <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> starts to eat up CPU or memory or
        if it <span class="quote">“<span class="quote">hangs,</span>”</span> you can use <a class="link" href="programs.html#mysqladmin" title="4.5.2 mysqladmin — Client for Administering a MySQL Server"><span class="command"><strong>mysqladmin
        processlist status</strong></span></a> to find out if someone is executing
        a query that takes a long time. It may be a good idea to run
        <a class="link" href="programs.html#mysqladmin" title="4.5.2 mysqladmin — Client for Administering a MySQL Server"><span class="command"><strong>mysqladmin -i10 processlist status</strong></span></a> in some
        window if you are experiencing performance problems or problems
        when new clients cannot connect.
      </p><p>
        The command <a class="link" href="programs.html#mysqladmin" title="4.5.2 mysqladmin — Client for Administering a MySQL Server"><span class="command"><strong>mysqladmin debug</strong></span></a> dumps some
        information about locks in use, used memory and query usage to
        the MySQL log file. This may help solve some problems. This
        command also provides some useful information even if you have
        not compiled MySQL for debugging!
      </p><p>
        If the problem is that some tables are getting slower and slower
        you should try to optimize the table with
        <a class="link" href="sql-syntax.html#optimize-table" title="13.7.3.4 OPTIMIZE TABLE Syntax"><code class="literal">OPTIMIZE TABLE</code></a> or
        <a class="link" href="programs.html#myisamchk" title="4.6.4 myisamchk — MyISAM Table-Maintenance Utility"><span class="command"><strong>myisamchk</strong></span></a>. See
        <a class="xref" href="server-administration.html" title="Chapter 5 MySQL Server Administration">Chapter 5, <i>MySQL Server Administration</i></a>. You should also check
        the slow queries with <a class="link" href="sql-syntax.html#explain" title="13.8.2 EXPLAIN Syntax"><code class="literal">EXPLAIN</code></a>.
      </p><p>
        You should also read the OS-specific section in this manual for
        problems that may be unique to your environment. See
        <a class="xref" href="installing.html#general-installation-issues" title="2.1 General Installation Guidance">Section 2.1, “General Installation Guidance”</a>.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="compiling-for-debugging"></a>28.5.1.1 Compiling MySQL for Debugging</h4>
</div>
</div>
</div>
<p>
          If you have some very specific problem, you can always try to
          debug MySQL. To do this you must configure MySQL with the
          <a class="link" href="installing.html#option_cmake_with_debug"><code class="option">-DWITH_DEBUG=1</code></a> option. You can
          check whether MySQL was compiled with debugging by doing:
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld --help</strong></span></a>. If the
          <a class="link" href="server-administration.html#option_mysqld_debug"><code class="option">--debug</code></a> flag is listed with the
          options then you have debugging enabled. <a class="link" href="programs.html#mysqladmin" title="4.5.2 mysqladmin — Client for Administering a MySQL Server"><span class="command"><strong>mysqladmin
          ver</strong></span></a> also lists the <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> version
          as <a class="link" href="programs.html#mysql" title="4.5.1 mysql — The MySQL Command-Line Tool"><span class="command"><strong>mysql ... --debug</strong></span></a> in this case.
        </p><p>
          If <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> stops crashing when you configure
          it with the <a class="link" href="installing.html#option_cmake_with_debug"><code class="option">-DWITH_DEBUG=1</code></a> CMake
          option, you probably have found a compiler bug or a timing bug
          within MySQL. In this case, you can try to add
          <code class="option">-g</code> using the
          <a class="link" href="installing.html#option_cmake_cmake_c_flags"><code class="option">CMAKE_C_FLAGS</code></a> and
          <a class="link" href="installing.html#option_cmake_cmake_cxx_flags"><code class="option">CMAKE_CXX_FLAGS</code></a> CMake options
          and not use <a class="link" href="installing.html#option_cmake_with_debug"><code class="option">-DWITH_DEBUG=1</code></a>. If
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> dies, you can at least attach to it
          with <span class="command"><strong>gdb</strong></span> or use <span class="command"><strong>gdb</strong></span> on
          the core file to find out what happened.
        </p><p>
          When you configure MySQL for debugging you automatically
          enable a lot of extra safety check functions that monitor the
          health of <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a>. If they find something
          <span class="quote">“<span class="quote">unexpected,</span>”</span> an entry is written to
          <code class="literal">stderr</code>, which
          <a class="link" href="programs.html#mysqld-safe" title="4.3.2 mysqld_safe — MySQL Server Startup Script"><span class="command"><strong>mysqld_safe</strong></span></a> directs to the error log! This
          also means that if you are having some unexpected problems
          with MySQL and are using a source distribution, the first
          thing you should do is to configure MySQL for debugging! (The
          second thing is to send mail to a MySQL mailing list and ask
          for help. See <a class="xref" href="introduction.html#mailing-lists" title="1.6.2 MySQL Mailing Lists">Section 1.6.2, “MySQL Mailing Lists”</a>. If you believe
          that you have found a bug, please use the instructions at
          <a class="xref" href="introduction.html#bug-reports" title="1.7 How to Report Bugs or Problems">Section 1.7, “How to Report Bugs or Problems”</a>.
        </p><p>
          In the Windows MySQL distribution,
          <code class="literal">mysqld.exe</code> is by default compiled with
          support for trace files.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="making-trace-files"></a>28.5.1.2 Creating Trace Files</h4>

</div>

</div>

</div>
<p>
          If the <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> server does not start or it
          crashes easily, you can try to create a trace file to find the
          problem.
        </p><p>
          To do this, you must have a <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> that has
          been compiled with debugging support. You can check this by
          executing <code class="literal">mysqld -V</code>. If the version number
          ends with <code class="literal">-debug</code>, it is compiled with
          support for trace files. (On Windows, the debugging server is
          named <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld-debug</strong></span></a> rather than
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a>.)
        </p><p>
          Start the <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> server with a trace log in
          <code class="filename">/tmp/mysqld.trace</code> on Unix or
          <code class="filename">\mysqld.trace</code> on Windows:
        </p><pre class="programlisting">
shell&gt; <strong class="userinput"><code>mysqld --debug</code></strong>
</pre><p>
          On Windows, you should also use the
          <a class="link" href="server-administration.html#option_mysqld_standalone"><code class="option">--standalone</code></a> flag to not start
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> as a service. In a console window,
          use this command:
        </p><pre class="programlisting">
C:\&gt; <strong class="userinput"><code>mysqld-debug --debug --standalone</code></strong>
</pre><p>
          After this, you can use the <code class="literal">mysql.exe</code>
          command-line tool in a second console window to reproduce the
          problem. You can stop the <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> server
          with <a class="link" href="programs.html#mysqladmin" title="4.5.2 mysqladmin — Client for Administering a MySQL Server"><span class="command"><strong>mysqladmin shutdown</strong></span></a>.
        </p><p>
          The trace file can become <span class="bold"><strong>very
          large</strong></span>! To generate a smaller trace file, you can
          use debugging options something like this:
        </p><p>
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld
          --debug=d,info,error,query,general,where:O,/tmp/mysqld.trace</strong></span></a>
        </p><p>
          This only prints information with the most interesting tags to
          the trace file.
        </p><p>
          If you make a bug report about this, please only send the
          lines from the trace file to the appropriate mailing list
          where something seems to go wrong! If you cannot locate the
          wrong place, you can open a bug report and upload the trace
          file to the report, so that a MySQL developer can take a look
          at it. For instructions, see <a class="xref" href="introduction.html#bug-reports" title="1.7 How to Report Bugs or Problems">Section 1.7, “How to Report Bugs or Problems”</a>.
        </p><p>
          The trace file is made with the
          <span class="bold"><strong>DBUG</strong></span> package by Fred Fish.
          See <a class="xref" href="extending-mysql.html#dbug-package" title="28.5.3 The DBUG Package">Section 28.5.3, “The DBUG Package”</a>.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="making-windows-dumps"></a>28.5.1.3 Using WER with PDB to create a Windows crashdump</h4>

</div>

</div>

</div>
<p>
          Program Database files (with suffix <code class="filename">pdb</code>)
          are included in the <span class="bold"><strong>ZIP Archive Debug
          Binaries &amp; Test Suite</strong></span> distribution of MySQL.
          These files provide information for debugging your MySQL
          installation in the event of a problem. This is a separate
          download from the standard MSI or Zip file.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
            The PDB files are available in a separate file labeled "ZIP
            Archive Debug Binaries &amp; Test Suite".
</p>
</div>
<p>
          The PDB file contains more detailed information about
          <code class="literal">mysqld</code> and other tools that enables more
          detailed trace and dump files to be created. You can use these
          with <span class="command"><strong>WinDbg</strong></span> or Visual Studio to debug
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a>.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
            The older <span class="emphasis"><em>Dr. Watson</em></span> debugging tool was
            removed in Microsoft Vista, with <span class="command"><strong>WinDbg</strong></span>
            being a common alternative.
</p>
</div>
<p>
          For more information on PDB files, see
          <a class="ulink" href="http://support.microsoft.com/kb/121366/" target="_top">Microsoft
          Knowledge Base Article 121366</a>. For more information on
          the debugging options available, see
          <a class="ulink" href="http://www.microsoft.com/whdc/devtools/debugging/default.mspx" target="_top">Debugging
          Tools for Windows</a>.
        </p><p>
          To use WinDbg, either install the full Windows Driver Kit
          (WDK) or install the standalone version.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
            The <code class="filename">.exe</code> and <code class="filename">.pbd</code>
            files must be an exact match (both version number and MySQL
            server edition) or WinDBG will complain while attempting to
            load the symbols.
</p>
</div>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
              To generate a minidump <code class="filename">mysqld.dmp</code>,
              enable the <a class="link" href="server-administration.html#option_mysqld_core-file"><code class="option">core-file</code></a> option
              under the [mysqld] section in <code class="filename">my.ini</code>.
              Restart the MySQL server after making these changes.
            </p></li><li class="listitem"><p>
              Create a directory to store the generated files, such as
              <code class="filename">c:\symbols</code>
            </p></li><li class="listitem"><p>
              Determine the path to your <span class="command"><strong>windbg.exe</strong></span>
              executable using the Find GUI or from the command line,
              for example: <code class="literal">dir /s /b windbg.exe</code> -- a
              common default is <span class="emphasis"><em>C:\Program Files\Debugging
              Tools for Windows (x64)\windbg.exe</em></span>
            </p></li><li class="listitem"><p>
              Launch <code class="filename">windbg.exe</code> giving it the paths
              to <code class="filename">mysqld.exe</code>,
              <code class="filename">mysqld.pdb</code>,
              <code class="filename">mysqld.dmp</code>, and the source code.
              Alternatively, pass in each path from the WinDbg GUI. For
              example:
            </p><pre class="programlisting">
<strong class="userinput"><code>
windbg.exe -i "C:\mysql-8.0.13-winx64\bin\"^
 -z "C:\mysql-8.0.13-winx64\data\mysqld.dmp"^
 -srcpath "E:\ade\mysql_archives\8.0\8.0.13\mysql-8.0.13"^
 -y "C:\mysql-8.0.13-winx64\bin;SRV*c:\symbols*http://msdl.microsoft.com/download/symbols"^
 -v -n -c "!analyze -vvvvv"
</code></strong>
</pre>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
                The <code class="literal">^</code> character and newline are
                removed by the Windows command line processor, so be
                sure the spaces remain intact.
</p>
</div>
</li></ol>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="using-gdb-on-mysqld"></a>28.5.1.4 Debugging mysqld under gdb</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm139899453785808"></a><p>
          On most systems you can also start <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a>
          from <span class="command"><strong>gdb</strong></span> to get more information if
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> crashes.
        </p><p>
          With some older <span class="command"><strong>gdb</strong></span> versions on Linux you
          must use <code class="literal">run --one-thread</code> if you want to be
          able to debug <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> threads. In this case,
          you can only have one thread active at a time. It is best to
          upgrade to <span class="command"><strong>gdb</strong></span> 5.1 because thread debugging
          works much better with this version!
        </p><p>
          NPTL threads (the new thread library on Linux) may cause
          problems while running <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> under
          <span class="command"><strong>gdb</strong></span>. Some symptoms are:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> hangs during startup (before it
              writes <code class="literal">ready for connections</code>).
            </p></li><li class="listitem"><p>
              <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> crashes during a
              <code class="literal">pthread_mutex_lock()</code> or
              <code class="literal">pthread_mutex_unlock()</code> call.
</p></li></ul>
</div>
<p>
          In this case, you should set the following environment
          variable in the shell before starting <span class="command"><strong>gdb</strong></span>:
        </p><pre class="programlisting">
LD_ASSUME_KERNEL=2.4.1
export LD_ASSUME_KERNEL
</pre><p>
          When running <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> under
          <span class="command"><strong>gdb</strong></span>, you should disable the stack trace
          with <a class="link" href="server-administration.html#option_mysqld_skip-stack-trace"><code class="option">--skip-stack-trace</code></a> to be
          able to catch segfaults within <span class="command"><strong>gdb</strong></span>.
        </p><p>
          Use the <a class="link" href="server-administration.html#option_mysqld_gdb"><code class="option">--gdb</code></a> option to
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> to install an interrupt handler for
          <code class="literal">SIGINT</code> (needed to stop
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> with <code class="literal">^C</code> to set
          breakpoints) and disable stack tracing and core file handling.
        </p><p>
          It is very hard to debug MySQL under <span class="command"><strong>gdb</strong></span> if
          you do a lot of new connections the whole time as
          <span class="command"><strong>gdb</strong></span> does not free the memory for old
          threads. You can avoid this problem by starting
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> with
          <a class="link" href="server-administration.html#sysvar_thread_cache_size"><code class="literal">thread_cache_size</code></a> set to a
          value equal to
          <a class="link" href="server-administration.html#sysvar_max_connections"><code class="literal">max_connections</code></a> + 1. In most
          cases just using
          <a class="link" href="server-administration.html#sysvar_thread_cache_size"><code class="option">--thread_cache_size=5'</code></a> helps a
          lot!
        </p><p>
          If you want to get a core dump on Linux if
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> dies with a SIGSEGV signal, you can
          start <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> with the
          <a class="link" href="server-administration.html#option_mysqld_core-file"><code class="option">--core-file</code></a> option. This core
          file can be used to make a backtrace that may help you find
          out why <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> died:
        </p><pre class="programlisting">
shell&gt; <strong class="userinput"><code>gdb mysqld core</code></strong>
gdb&gt;   backtrace full
gdb&gt;   quit
</pre><p>
          See <a class="xref" href="error-handling.html#crashing" title="B.5.3.3 What to Do If MySQL Keeps Crashing">Section B.5.3.3, “What to Do If MySQL Keeps Crashing”</a>.
        </p><p>
          If you are using <span class="command"><strong>gdb</strong></span> 4.17.x or above on
          Linux, you should install a <code class="filename">.gdb</code> file,
          with the following information, in your current directory:
        </p><pre class="programlisting">
set print sevenbit off
handle SIGUSR1 nostop noprint
handle SIGUSR2 nostop noprint
handle SIGWAITING nostop noprint
handle SIGLWP nostop noprint
handle SIGPIPE nostop
handle SIGALRM nostop
handle SIGHUP nostop
handle SIGTERM nostop noprint
</pre><p>
          If you have problems debugging threads with
          <span class="command"><strong>gdb</strong></span>, you should download gdb 5.x and try
          this instead. The new <span class="command"><strong>gdb</strong></span> version has very
          improved thread handling!
        </p><p>
          Here is an example how to debug <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a>:
        </p><pre class="programlisting">
shell&gt; <strong class="userinput"><code>gdb /usr/local/libexec/mysqld</code></strong>
gdb&gt; run
...
backtrace full # Do this when mysqld crashes
</pre><p>
          Include the preceding output in a bug report, which you can
          file using the instructions in <a class="xref" href="introduction.html#bug-reports" title="1.7 How to Report Bugs or Problems">Section 1.7, “How to Report Bugs or Problems”</a>.
        </p><p>
          If <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> hangs, you can try to use some
          system tools like <code class="literal">strace</code> or
          <code class="literal">/usr/proc/bin/pstack</code> to examine where
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> has hung.
        </p><pre class="programlisting">
strace /tmp/log libexec/mysqld
</pre><a class="indexterm" name="idm139899453727520"></a><a class="indexterm" name="idm139899453726448"></a><a class="indexterm" name="idm139899453725376"></a><a class="indexterm" name="idm139899453724288"></a><p>
          If you are using the Perl <code class="literal">DBI</code> interface,
          you can turn on debugging information by using the
          <code class="literal">trace</code> method or by setting the
          <code class="literal">DBI_TRACE</code> environment variable.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="using-stack-trace"></a>28.5.1.5 Using a Stack Trace</h4>

</div>

</div>

</div>
<p>
          On some operating systems, the error log contains a stack
          trace if <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> dies unexpectedly. You can
          use this to find out where (and maybe why)
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> died. See
          <a class="xref" href="server-administration.html#error-log" title="5.4.2 The Error Log">Section 5.4.2, “The Error Log”</a>. To get a stack trace, you must
          not compile <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> with the
          <code class="option">-fomit-frame-pointer</code> option to gcc. See
          <a class="xref" href="extending-mysql.html#compiling-for-debugging" title="28.5.1.1 Compiling MySQL for Debugging">Section 28.5.1.1, “Compiling MySQL for Debugging”</a>.
        </p><p>
          A stack trace in the error log looks something like this:
        </p><pre class="programlisting">
mysqld got signal 11;
Attempting backtrace. You can use the following information
to find out where mysqld died. If you see no messages after
this, something went terribly wrong...

stack_bottom = 0x41fd0110 thread_stack 0x40000
mysqld(my_print_stacktrace+0x32)[0x9da402]
mysqld(handle_segfault+0x28a)[0x6648e9]
/lib/libpthread.so.0[0x7f1a5af000f0]
/lib/libc.so.6(strcmp+0x2)[0x7f1a5a10f0f2]
mysqld(_Z21check_change_passwordP3THDPKcS2_Pcj+0x7c)[0x7412cb]
mysqld(_ZN16set_var_password5checkEP3THD+0xd0)[0x688354]
mysqld(_Z17sql_set_variablesP3THDP4ListI12set_var_baseE+0x68)[0x688494]
mysqld(_Z21mysql_execute_commandP3THD+0x41a0)[0x67a170]
mysqld(_Z11mysql_parseP3THDPKcjPS2_+0x282)[0x67f0ad]
mysqld(_Z16dispatch_command19enum_server_commandP3THDPcj+0xbb7[0x67fdf8]
mysqld(_Z10do_commandP3THD+0x24d)[0x6811b6]
mysqld(handle_one_connection+0x11c)[0x66e05e]
</pre><p>
          If resolution of function names for the trace fails, the trace
          contains less information:
        </p><pre class="programlisting">
mysqld got signal 11;
Attempting backtrace. You can use the following information
to find out where mysqld died. If you see no messages after
this, something went terribly wrong...

stack_bottom = 0x41fd0110 thread_stack 0x40000
[0x9da402]
[0x6648e9]
[0x7f1a5af000f0]
[0x7f1a5a10f0f2]
[0x7412cb]
[0x688354]
[0x688494]
[0x67a170]
[0x67f0ad]
[0x67fdf8]
[0x6811b6]
[0x66e05e]
</pre><p>
          In the latter case, you can use the
          <a class="link" href="programs.html#resolve-stack-dump" title="4.7.3 resolve_stack_dump — Resolve Numeric Stack Trace Dump to Symbols"><span class="command"><strong>resolve_stack_dump</strong></span></a> utility to determine
          where <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> died by using the following
          procedure:
</p>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
              Copy the numbers from the stack trace to a file, for
              example <code class="filename">mysqld.stack</code>. The numbers
              should not include the surrounding square brackets:
            </p><pre class="programlisting">
0x9da402
0x6648e9
0x7f1a5af000f0
0x7f1a5a10f0f2
0x7412cb
0x688354
0x688494
0x67a170
0x67f0ad
0x67fdf8
0x6811b6
0x66e05e
</pre></li><li class="listitem"><p>
              Make a symbol file for the <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a>
              server:
            </p><pre class="programlisting">
shell&gt; <strong class="userinput"><code>nm -n libexec/mysqld &gt; /tmp/mysqld.sym</code></strong>
</pre><p>
              If <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> is not linked statically, use
              the following command instead:
            </p><pre class="programlisting">
shell&gt; <strong class="userinput"><code>nm -D -n libexec/mysqld &gt; /tmp/mysqld.sym</code></strong>
</pre><p>
              If you want to decode C++ symbols, use the
              <code class="option">--demangle</code>, if available, to
              <span class="command"><strong>nm</strong></span>. If your version of
              <span class="command"><strong>nm</strong></span> does not have this option, you will
              need to use the <span class="command"><strong>c++filt</strong></span> command after
              the stack dump has been produced to demangle the C++
              names.
            </p></li><li class="listitem"><p>
              Execute the following command:
            </p><pre class="programlisting">
shell&gt; <strong class="userinput"><code>resolve_stack_dump -s /tmp/mysqld.sym -n mysqld.stack</code></strong>
</pre><p>
              If you were not able to include demangled C++ names in
              your symbol file, process the
              <a class="link" href="programs.html#resolve-stack-dump" title="4.7.3 resolve_stack_dump — Resolve Numeric Stack Trace Dump to Symbols"><span class="command"><strong>resolve_stack_dump</strong></span></a> output using
              <span class="command"><strong>c++filt</strong></span>:
            </p><pre class="programlisting">
shell&gt; <strong class="userinput"><code>resolve_stack_dump -s /tmp/mysqld.sym -n mysqld.stack | c++filt</code></strong>
</pre><p>
              This prints out where <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> died. If
              that does not help you find out why
              <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> died, you should create a bug
              report and include the output from the preceding command
              with the bug report.
            </p><p>
              However, in most cases it does not help us to have just a
              stack trace to find the reason for the problem. To be able
              to locate the bug or provide a workaround, in most cases
              we need to know the statement that killed
              <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> and preferably a test case so
              that we can repeat the problem! See
              <a class="xref" href="introduction.html#bug-reports" title="1.7 How to Report Bugs or Problems">Section 1.7, “How to Report Bugs or Problems”</a>.
</p></li></ol>
</div>
<p>
          Newer versions of <code class="literal">glibc</code> stack trace
          functions also print the address as relative to the object. On
          <code class="literal">glibc</code>-based systems (Linux), the trace for
          a crash within a plugin looks something like:
        </p><pre class="programlisting">
plugin/auth/auth_test_plugin.so(+0x9a6)[0x7ff4d11c29a6]
</pre><p>
          To translate the relative address (<code class="literal">+0x9a6</code>)
          into a file name and line number, use this command:
        </p><pre class="programlisting">
shell&gt; <strong class="userinput"><code>addr2line -fie auth_test_plugin.so 0x9a6</code></strong>
auth_test_plugin
mysql-trunk/plugin/auth/test_plugin.c:65
</pre><p>
          The <span class="command"><strong>addr2line</strong></span> utility is part of the
          <code class="literal">binutils</code> package on Linux.
        </p><p>
          On Solaris, the procedure is similar. The Solaris
          <code class="literal">printstack()</code> already prints relative
          addresses:
        </p><pre class="programlisting">
plugin/auth/auth_test_plugin.so:0x1510
</pre><p>
          To translate, use this command:
        </p><pre class="programlisting">
shell&gt; <strong class="userinput"><code>gaddr2line -fie auth_test_plugin.so 0x1510</code></strong>
mysql-trunk/plugin/auth/test_plugin.c:88
</pre><p>
          Windows already prints the address, function name and line:
        </p><pre class="programlisting">
000007FEF07E10A4 auth_test_plugin.dll!auth_test_plugin()[test_plugin.c:72]
</pre>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="using-log-files"></a>28.5.1.6 Using Server Logs to Find Causes of Errors in mysqld</h4>

</div>

</div>

</div>
<p>
          Note that before starting <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> with the
          general query log enabled, you should check all your tables
          with <a class="link" href="programs.html#myisamchk" title="4.6.4 myisamchk — MyISAM Table-Maintenance Utility"><span class="command"><strong>myisamchk</strong></span></a>. See
          <a class="xref" href="server-administration.html" title="Chapter 5 MySQL Server Administration">Chapter 5, <i>MySQL Server Administration</i></a>.
        </p><p>
          If <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> dies or hangs, you should start
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> with the general query log enabled.
          See <a class="xref" href="server-administration.html#query-log" title="5.4.3 The General Query Log">Section 5.4.3, “The General Query Log”</a>. When
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> dies again, you can examine the end
          of the log file for the query that killed
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a>.
        </p><p>
          If you use the default general query log file, the log is
          stored in the database directory as
          <code class="filename"><em class="replaceable"><code>host_name</code></em>.log</code>
          In most cases it is the last query in the log file that killed
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a>, but if possible you should verify
          this by restarting <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> and executing the
          found query from the <a class="link" href="programs.html#mysql" title="4.5.1 mysql — The MySQL Command-Line Tool"><span class="command"><strong>mysql</strong></span></a> command-line
          tools. If this works, you should also test all complicated
          queries that did not complete.
        </p><p>
          You can also try the command
          <a class="link" href="sql-syntax.html#explain" title="13.8.2 EXPLAIN Syntax"><code class="literal">EXPLAIN</code></a> on all
          <a class="link" href="sql-syntax.html#select" title="13.2.10 SELECT Syntax"><code class="literal">SELECT</code></a> statements that takes a
          long time to ensure that <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> is using
          indexes properly. See <a class="xref" href="sql-syntax.html#explain" title="13.8.2 EXPLAIN Syntax">Section 13.8.2, “EXPLAIN Syntax”</a>.
        </p><p>
          You can find the queries that take a long time to execute by
          starting <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> with the slow query log
          enabled. See <a class="xref" href="server-administration.html#slow-query-log" title="5.4.5 The Slow Query Log">Section 5.4.5, “The Slow Query Log”</a>.
        </p><p>
          If you find the text <code class="literal">mysqld restarted</code> in
          the error log (normally a file named
          <code class="filename"><em class="replaceable"><code>host_name</code></em>.err</code>)
          you probably have found a query that causes
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> to fail. If this happens, you should
          check all your tables with <a class="link" href="programs.html#myisamchk" title="4.6.4 myisamchk — MyISAM Table-Maintenance Utility"><span class="command"><strong>myisamchk</strong></span></a> (see
          <a class="xref" href="server-administration.html" title="Chapter 5 MySQL Server Administration">Chapter 5, <i>MySQL Server Administration</i></a>), and test the queries
          in the MySQL log files to see whether one fails. If you find
          such a query, try first upgrading to the newest MySQL version.
          If this does not help and you cannot find anything in the
          <code class="literal">mysql</code> mail archive, you should report the
          bug to a MySQL mailing list. The mailing lists are described
          at <a class="ulink" href="http://lists.mysql.com/" target="_top">http://lists.mysql.com/</a>, which also has
          links to online list archives.
        </p><p>
          If you have started <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> with
          <a class="link" href="server-administration.html#option_mysqld_myisam-recover-options"><code class="option">--myisam-recover-options</code></a>, MySQL
          automatically checks and tries to repair
          <code class="literal">MyISAM</code> tables if they are marked as 'not
          closed properly' or 'crashed'. If this happens, MySQL writes
          an entry in the <code class="literal">hostname.err</code> file
          <code class="literal">'Warning: Checking table ...'</code> which is
          followed by <code class="literal">Warning: Repairing table</code> if the
          table needs to be repaired. If you get a lot of these errors,
          without <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> having died unexpectedly
          just before, then something is wrong and needs to be
          investigated further. See <a class="xref" href="server-administration.html#server-options" title="5.1.4 Server Command Options">Section 5.1.4, “Server Command Options”</a>.
        </p><p>
          When the server detects <code class="literal">MyISAM</code> table
          corruption, it writes additional information to the error log,
          such as the name and line number of the source file, and the
          list of threads accessing the table. Example: <code class="literal">Got an
          error from thread_id=1, mi_dynrec.c:368</code>. This is
          useful information to include in bug reports.
        </p><p>
          It is not a good sign if <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> did die
          unexpectedly, but in this case, you should not investigate the
          <code class="literal">Checking table...</code> messages, but instead try
          to find out why <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> died.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="reproducible-test-case"></a>28.5.1.7 Making a Test Case If You Experience Table Corruption</h4>

</div>

</div>

</div>
<p>
          The following procedure applies to
          <a class="link" href="storage-engines.html#myisam-storage-engine" title="16.2 The MyISAM Storage Engine"><code class="literal">MyISAM</code></a> tables. For information
          about steps to take when encountering
          <code class="literal">InnoDB</code> table corruption, see
          <a class="xref" href="introduction.html#bug-reports" title="1.7 How to Report Bugs or Problems">Section 1.7, “How to Report Bugs or Problems”</a>.
        </p><p>
          If you encounter corrupted <a class="link" href="storage-engines.html#myisam-storage-engine" title="16.2 The MyISAM Storage Engine"><code class="literal">MyISAM</code></a>
          tables or if <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> always fails after some
          update statements, you can test whether the issue is
          reproducible by doing the following:
</p>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
              Stop the MySQL daemon with <a class="link" href="programs.html#mysqladmin" title="4.5.2 mysqladmin — Client for Administering a MySQL Server"><span class="command"><strong>mysqladmin
              shutdown</strong></span></a>.
            </p></li><li class="listitem"><p>
              Make a backup of the tables to guard against the very
              unlikely case that the repair does something bad.
            </p></li><li class="listitem"><p>
              Check all tables with <a class="link" href="programs.html#myisamchk" title="4.6.4 myisamchk — MyISAM Table-Maintenance Utility"><span class="command"><strong>myisamchk -s
              database/*.MYI</strong></span></a>. Repair any corrupted tables with
              <a class="link" href="programs.html#myisamchk" title="4.6.4 myisamchk — MyISAM Table-Maintenance Utility"><span class="command"><strong>myisamchk -r
              database/<em class="replaceable"><code>table</code></em>.MYI</strong></span></a>.
            </p></li><li class="listitem"><p>
              Make a second backup of the tables.
            </p></li><li class="listitem"><p>
              Remove (or move away) any old log files from the MySQL
              data directory if you need more space.
            </p></li><li class="listitem"><p>
              Start <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> with the binary log
              enabled. If you want to find a statement that crashes
              <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a>, you should start the server
              with the general query log enabled as well. See
              <a class="xref" href="server-administration.html#query-log" title="5.4.3 The General Query Log">Section 5.4.3, “The General Query Log”</a>, and
              <a class="xref" href="server-administration.html#binary-log" title="5.4.4 The Binary Log">Section 5.4.4, “The Binary Log”</a>.
            </p></li><li class="listitem"><p>
              When you have gotten a crashed table, stop the
              <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> server.
            </p></li><li class="listitem"><p>
              Restore the backup.
            </p></li><li class="listitem"><p>
              Restart the <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> server
              <span class="emphasis"><em>without</em></span> the binary log enabled.
            </p></li><li class="listitem"><p>
              Re-execute the statements with <a class="link" href="programs.html#mysqlbinlog" title="4.6.8 mysqlbinlog — Utility for Processing Binary Log Files"><span class="command"><strong>mysqlbinlog
              binary-log-file | mysql</strong></span></a>. The binary log is saved
              in the MySQL database directory with the name
              <code class="literal">hostname-bin.<em class="replaceable"><code>NNNNNN</code></em></code>.
            </p></li><li class="listitem"><p>
              If the tables are corrupted again or you can get
              <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> to die with the above command,
              you have found a reproducible bug. FTP the tables and the
              binary log to our bugs database using the instructions
              given in <a class="xref" href="introduction.html#bug-reports" title="1.7 How to Report Bugs or Problems">Section 1.7, “How to Report Bugs or Problems”</a>. If you are a
              support customer, you can use the MySQL Customer Support
              Center (<a class="ulink" href="http://www.mysql.com/support/" target="_top">http://www.mysql.com/support/</a>) to alert the
              MySQL team about the problem and have it fixed as soon as
              possible.
</p></li></ol>
</div>

</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="debugging-client"></a>28.5.2 Debugging a MySQL Client</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm139899453588192"></a><a class="indexterm" name="idm139899453586736"></a><p>
        To be able to debug a MySQL client with the integrated debug
        package, you should configure MySQL with
        <a class="link" href="installing.html#option_cmake_with_debug"><code class="option">-DWITH_DEBUG=1</code></a>. See
        <a class="xref" href="installing.html#source-configuration-options" title="2.9.4 MySQL Source-Configuration Options">Section 2.9.4, “MySQL Source-Configuration Options”</a>.
      </p><a class="indexterm" name="idm139899453583008"></a><a class="indexterm" name="idm139899453581968"></a><p>
        Before running a client, you should set the
        <code class="literal">MYSQL_DEBUG</code> environment variable:
      </p><pre class="programlisting">
shell&gt; <strong class="userinput"><code>MYSQL_DEBUG=d:t:O,/tmp/client.trace</code></strong>
shell&gt; <strong class="userinput"><code>export MYSQL_DEBUG</code></strong>
</pre><p>
        This causes clients to generate a trace file in
        <code class="filename">/tmp/client.trace</code>.
      </p><p>
        If you have problems with your own client code, you should
        attempt to connect to the server and run your query using a
        client that is known to work. Do this by running
        <a class="link" href="programs.html#mysql" title="4.5.1 mysql — The MySQL Command-Line Tool"><span class="command"><strong>mysql</strong></span></a> in debugging mode (assuming that you
        have compiled MySQL with debugging on):
      </p><pre class="programlisting">
shell&gt; <strong class="userinput"><code>mysql --debug=d:t:O,/tmp/client.trace</code></strong>
</pre><p>
        This provides useful information in case you mail a bug report.
        See <a class="xref" href="introduction.html#bug-reports" title="1.7 How to Report Bugs or Problems">Section 1.7, “How to Report Bugs or Problems”</a>.
      </p><p>
        If your client crashes at some 'legal' looking code, you should
        check that your <code class="filename">mysql.h</code> include file
        matches your MySQL library file. A very common mistake is to use
        an old <code class="filename">mysql.h</code> file from an old MySQL
        installation with new MySQL library.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="dbug-package"></a>28.5.3 The DBUG Package</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm139899453568208"></a><p>
        The MySQL server and most MySQL clients are compiled with the
        DBUG package originally created by Fred Fish. When you have
        configured MySQL for debugging, this package makes it possible
        to get a trace file of what the program is doing. See
        <a class="xref" href="extending-mysql.html#making-trace-files" title="28.5.1.2 Creating Trace Files">Section 28.5.1.2, “Creating Trace Files”</a>.
      </p><p>
        This section summarizes the argument values that you can specify
        in debug options on the command line for MySQL programs that
        have been built with debugging support. For more information
        about programming with the DBUG package, see the DBUG manual in
        the <code class="filename">dbug</code> directory of MySQL source
        distributions. It's best to use a recent distribution to get the
        most updated DBUG manual.
      </p><p>
        The DBUG package can be used by invoking a program with the
        <code class="option">--debug[=<em class="replaceable"><code>debug_options</code></em>]</code>
        or <code class="option">-#
        [<em class="replaceable"><code>debug_options</code></em>]</code> option. If
        you specify the <code class="option">--debug</code> or <code class="option">-#</code>
        option without a <em class="replaceable"><code>debug_options</code></em> value,
        most MySQL programs use a default value. The server default is
        <code class="literal">d:t:i:o,/tmp/mysqld.trace</code> on Unix and
        <code class="literal">d:t:i:O,\mysqld.trace</code> on Windows. The effect
        of this default is:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">d</code>: Enable output for all debug macros
          </p></li><li class="listitem"><p>
            <code class="literal">t</code>: Trace function calls and exits
          </p></li><li class="listitem"><p>
            <code class="literal">i</code>: Add PID to output lines
          </p></li><li class="listitem"><p>
            <code class="literal">o,/tmp/mysqld.trace</code>,
            <code class="literal">O,\mysqld.trace</code>: Set the debug output
            file.
</p></li></ul>
</div>
<p>
        Most client programs use a default
        <em class="replaceable"><code>debug_options</code></em> value of
        <code class="literal">d:t:o,/tmp/<em class="replaceable"><code>program_name</code></em>.trace</code>,
        regardless of platform.
      </p><p>
        Here are some example debug control strings as they might be
        specified on a shell command line:
      </p><pre class="programlisting">
--debug=d:t
--debug=d:f,main,subr1:F:L:t,20
--debug=d,input,output,files:n
--debug=d:t:i:O,\\mysqld.trace
</pre><p>
        For <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a>, it is also possible to change
        DBUG settings at runtime by setting the
        <a class="link" href="server-administration.html#sysvar_debug"><code class="literal">debug</code></a> system variable. This
        variable has global and session values:
      </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>SET GLOBAL debug = '<em class="replaceable"><code>debug_options</code></em>';</code></strong>
mysql&gt; <strong class="userinput"><code>SET SESSION debug = '<em class="replaceable"><code>debug_options</code></em>';</code></strong>
</pre><p>
        Changes at runtime require the
        <a class="link" href="security.html#priv_system-variables-admin"><code class="literal">SYSTEM_VARIABLES_ADMIN</code></a> or
        <a class="link" href="security.html#priv_super"><code class="literal">SUPER</code></a> privilege, even for the
        session value.
      </p><p>
        The <em class="replaceable"><code>debug_options</code></em> value is a sequence
        of colon-separated fields:
      </p><pre class="programlisting">
field_1:field_2:...:field_<em class="replaceable"><code>N</code></em>
</pre><p>
        Each field within the value consists of a mandatory flag
        character, optionally preceded by a <code class="literal">+</code> or
        <code class="literal">-</code> character, and optionally followed by a
        comma-delimited list of modifiers:
      </p><pre class="programlisting">
[+|-]flag[,modifier,modifier,...,modifier]
</pre><p>
        The following table describes the permitted flag characters.
        Unrecognized flag characters are silently ignored.
</p>
<div class="informaltable">
<table frame="all" summary="Descriptions of permitted debug_options flag characters."><col width="8%"><col width="92%"><thead><tr>
            <th scope="col"><p>
                Flag
              </p></th>
            <th scope="col"><p>
                Description
              </p></th>
          </tr></thead><tbody><tr>
            <td scope="row"><p>
                <code class="literal">d</code>
              </p></td>
            <td><p>
                Enable output from DBUG_<em class="replaceable"><code>XXX</code></em>
                macros for the current state. May be followed by a list
                of keywords, which enables output only for the DBUG
                macros with that keyword. An empty list of keywords
                enables output for all macros.
              </p><p>
                In MySQL, common debug macro keywords to enable are
                <code class="literal">enter</code>, <code class="literal">exit</code>,
                <code class="literal">error</code>, <code class="literal">warning</code>,
                <code class="literal">info</code>, and <code class="literal">loop</code>.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                <code class="literal">D</code>
              </p></td>
            <td><p>
                Delay after each debugger output line. The argument is
                the delay, in tenths of seconds, subject to machine
                capabilities. For example, <code class="literal">D,20</code>
                specifies a delay of two seconds.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                <code class="literal">f</code>
              </p></td>
            <td><p>
                Limit debugging, tracing, and profiling to the list of
                named functions. An empty list enables all functions.
                The appropriate <code class="literal">d</code> or
                <code class="literal">t</code> flags must still be given; this
                flag only limits their actions if they are enabled.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                <code class="literal">F</code>
              </p></td>
            <td><p>
                Identify the source file name for each line of debug or
                trace output.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                <code class="literal">i</code>
              </p></td>
            <td><p>
                Identify the process with the PID or thread ID for each
                line of debug or trace output.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                <code class="literal">L</code>
              </p></td>
            <td><p>
                Identify the source file line number for each line of
                debug or trace output.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                <code class="literal">n</code>
              </p></td>
            <td><p>
                Print the current function nesting depth for each line
                of debug or trace output.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                <code class="literal">N</code>
              </p></td>
            <td><p>
                Number each line of debug output.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                <code class="literal">o</code>
              </p></td>
            <td><p>
                Redirect the debugger output stream to the specified
                file. The default output is <code class="literal">stderr</code>.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                <code class="literal">O</code>
              </p></td>
            <td><p>
                Like <code class="literal">o</code>, but the file is really
                flushed between each write. When needed, the file is
                closed and reopened between each write.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                <code class="literal">p</code>
              </p></td>
            <td><p>
                Limit debugger actions to specified processes. A process
                must be identified with the
                <code class="literal">DBUG_PROCESS</code> macro and match one in
                the list for debugger actions to occur.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                <code class="literal">P</code>
              </p></td>
            <td><p>
                Print the current process name for each line of debug or
                trace output.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                <code class="literal">r</code>
              </p></td>
            <td><p>
                When pushing a new state, do not inherit the previous
                state's function nesting level. Useful when the output
                is to start at the left margin.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                <code class="literal">S</code>
              </p></td>
            <td><p>
                Do function <code class="literal">_sanity(_file_,_line_)</code> at
                each debugged function until
                <code class="literal">_sanity()</code> returns something that
                differs from 0.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                <code class="literal">t</code>
              </p></td>
            <td><p>
                Enable function call/exit trace lines. May be followed
                by a list (containing only one modifier) giving a
                numeric maximum trace level, beyond which no output
                occurs for either debugging or tracing macros. The
                default is a compile time option.
              </p></td>
</tr></tbody></table>
</div>
<p>
        The leading <code class="literal">+</code> or <code class="literal">-</code>
        character and trailing list of modifiers are used for flag
        characters such as <code class="literal">d</code> or <code class="literal">f</code>
        that can enable a debug operation for all applicable modifiers
        or just some of them:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            With no leading <code class="literal">+</code> or
            <code class="literal">-</code>, the flag value is set to exactly the
            modifier list as given.
          </p></li><li class="listitem"><p>
            With a leading <code class="literal">+</code> or <code class="literal">-</code>,
            the modifiers in the list are added to or subtracted from
            the current modifier list.
</p></li></ul>
</div>
<p>
        The following examples show how this works for the
        <code class="literal">d</code> flag. An empty <code class="literal">d</code> list
        enabled output for all debug macros. A nonempty list enables
        output only for the macro keywords in the list.
      </p><p>
        These statements set the <code class="literal">d</code> value to the
        modifier list as given:
      </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>SET debug = 'd';</code></strong>
mysql&gt; <strong class="userinput"><code>SELECT @@debug;</code></strong>
+---------+
| @@debug |
+---------+
| d       |
+---------+
mysql&gt; <strong class="userinput"><code>SET debug = 'd,error,warning';</code></strong>
mysql&gt; <strong class="userinput"><code>SELECT @@debug;</code></strong>
+-----------------+
| @@debug         |
+-----------------+
| d,error,warning |
+-----------------+
</pre><p>
        A leading <code class="literal">+</code> or <code class="literal">-</code> adds to
        or subtracts from the current <code class="literal">d</code> value:
      </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>SET debug = '+d,loop';</code></strong>
mysql&gt; <strong class="userinput"><code>SELECT @@debug;</code></strong>
+----------------------+
| @@debug              |
+----------------------+
| d,error,warning,loop |
+----------------------+
mysql&gt; <strong class="userinput"><code>SET debug = '-d,error,loop';</code></strong>
mysql&gt; <strong class="userinput"><code>SELECT @@debug;</code></strong>
+-----------+
| @@debug   |
+-----------+
| d,warning |
+-----------+
</pre><p>
        Adding to <span class="quote">“<span class="quote">all macros enabled</span>”</span> results in no
        change:
      </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>SET debug = 'd';</code></strong>
mysql&gt; <strong class="userinput"><code>SELECT @@debug;</code></strong>
+---------+
| @@debug |
+---------+
| d       |
+---------+
mysql&gt; <strong class="userinput"><code>SET debug = '+d,loop';</code></strong>
mysql&gt; <strong class="userinput"><code>SELECT @@debug;</code></strong>
+---------+
| @@debug |
+---------+
| d       |
+---------+
</pre><p>
        Disabling all enabled macros disables the <code class="literal">d</code>
        flag entirely:
      </p><pre class="programlisting">
mysql&gt; <strong class="userinput"><code>SET debug = 'd,error,loop';</code></strong>
mysql&gt; <strong class="userinput"><code>SELECT @@debug;</code></strong>
+--------------+
| @@debug      |
+--------------+
| d,error,loop |
+--------------+
mysql&gt; <strong class="userinput"><code>SET debug = '-d,error,loop';</code></strong>
mysql&gt; <strong class="userinput"><code>SELECT @@debug;</code></strong>
+---------+
| @@debug |
+---------+
|         |
+---------+
</pre>
</div>

</div>

</div>
<div class="copyright-footer">

</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="connectors-apis.html">Prev</a></td>
<td width="20%" align="center"><a accesskey="u" href="">Up</a></td>
<td width="40%" align="right"> <a accesskey="n" href="mysql-enterprise.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Chapter 27 Connectors and APIs</td>
<td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td>
<td width="40%" align="right" valign="top">Chapter 29 MySQL Enterprise Edition</td>
</tr>
</table>
</div>
</body>
</html>
